Menggunakan awk
:
awk -v a='2,4,5,7' -v b='1,2,5,8' '
BEGIN { split(a, ax, ","); split(b, bx, ",");
for(n in ax) mapping[ bx[n] ] =ax[n];
};
NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };
{ print (FNR in hold)? hold[FNR]: $0; }' fileB fileA
Di sini, kami memberikan nomor baris sebagai awk -v
ariable di a='...'
(untuk fileA) dan b='...'
(untuk fileB), lalu kita split()
mereka ke dalam array pada karakter koma sebagai pemisah (perhatikan bahwa a
dan b
adalah variabel, sedangkan sekarang ax
dan bx
adalah array).
lalu kita membuat mapping
lainnya larik dari ax
dan bx
array untuk memetakan baris yang harus diganti di fileA dengan baris dari fileB;
sekarang kunci (atau indeks) dari mapping
array adalah nomor baris dari fileB dan nilai dari kunci ini adalah nomor baris dari fileA, seperti di bawah ini:
mapping
array adalah:
Key Value
1 2
2 4
5 5
8 7
jadi sekarang yang kita butuhkan yaitu hanya membaca nomor baris dari fileB yang cocok dengan kunci di atas (FNR dari 1
, 2
, 5
dan 8
), jadi kami melakukannya dengan:
NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };
OK, sekarang berapa nilai dari mapping[FNR]
? jika Anda memeriksa mapping
array di atas, yaitu:
mapping[1] --> 2; then-we-have hold[ mapping[1] ] --> hold[2]=$0
mapping[2] --> 4; then-we-have hold[ mapping[2] ] --> hold[4]=$0
mapping[5] --> 5; then-we-have hold[ mapping[5] ] --> hold[5]=$0
mapping[8] --> 7; then-we-have hold[ mapping[8] ] --> hold[7]=$0
jadi kami menggunakan nilai mapping
array sebagai kunci untuk hold
array dan hold
array sekarang berisi:
Key Value
2 Argentina
4 Switzerland
5 Denmark
7 Colombia
sekarang langkah terakhir adalah menggunakan kunci di hold
array sebagai nomor baris yang cocok di fileA dan ganti baris itu dengan nilai kunci dari hold
array jika nomor baris itu ditemukan dalam array atau cetak baris itu sendiri jika tidak ditemukan (operator Ternary:condition? if-true : if-false
), dan kami melakukannya dengan:
{ print (FNR in hold)? hold[FNR]: $0; }
Menggunakan sed
standar :
$ printf '%ds/^/%dc\\\\\\\n/p\n' 1 2 2 4 5 5 8 7 | sed -n -f /dev/stdin fileB | sed -f /dev/stdin fileA
Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia
Saluran perintah,
printf '%ds/^/%dc\\\\\\\n/p\n' 1 2 2 4 5 5 8 7 |
sed -n -f /dev/stdin fileB |
sed -f /dev/stdin fileA
pertama menghasilkan sed
pernyataan pengganti untuk setiap pasangan nomor baris menggunakan printf
. Output dari printf
panggilan adalah sed
berikut skrip:
1s/^/2c\\\
/p
2s/^/4c\\\
/p
5s/^/5c\\\
/p
8s/^/7c\\\
/p
sed
ini skrip bekerja pada baris 1, 2, 5, dan 8, dan menyisipkan nc\
diikuti oleh baris baru literal (untuk beberapa nomor baris n
) di awal baris yang terpengaruh.
Menjalankan ini di fileB
(dengan sed -n
) menghasilkan sed
baru skrip:
2c\
Argentina
4c\
Switzerland
5c\
Denmark
7c\
Colombia
c
perintah mengganti baris dengan teks setelah \
, sehingga skrip akan menggantikan baris 2, 4, 5, dan 7.
Menerapkan ini ke fileA
menghasilkan hasilnya.
Membaca nomor baris dari file yang kolom pertamanya berisi nomor baris untuk fileB
, dan kolom kedua berisi nomor baris untuk fileA
:
$ cat number-pairs
1 2
2 4
5 5
8 7
$ awk '{ printf "%ds/^/%dc\\\\\\\n/p\n", $1, $2 }' number-pairs | sed -n -f /dev/stdin fileB | sed -f /dev/stdin fileA
Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia
Anda jelas dapat menukar $1
dan $2
di dalamnya awk
ekspresi jika Anda ingin menyimpan kolom dalam urutan yang berlawanan.