多くの行を含むfileA.txtがあり、特定の行を複数行を含む2番目のファイルfileB.txtの他の特定の行に置き換えたいと思います。
例: ファイル A.txt
Italy
Korea
USA
England
Peru
Japan
Uruguay
ファイルB.txt
Argentina
Switzerland
Spain
Greece
Denmark
Singapore
Thailand
Colombia
最初のファイルの2、4、5、7行を2番目のファイルの1、2、5、8行に置き換えたいと思います。
出力:
Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia
awkやsedでできるようですが、awkの場合、このコードは2番目のファイルに関する行情報を提供していないようです。
awk 'NR==FNR{ a[$2]=$1; next }FNR in a{ $0=a[FNR] }1' fileA.txt fileB.txt
どんな提案がありますか?
ベストアンサー1
使用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
ここでは、行番号を次のように使用します。アッ -v
a='...'
変数が(ファイルAの場合)およびb='...'
(ファイルBの場合)にある場合split()
これをコンマ文字で区切られた配列に入れます(a
およびはb
変数、現在ax
はbx
配列です)。
mapping
次に、ax
配列から別の配列を作成し、bx
fileAの行をfileBの行に置き換える必要があります。
現在のキー(またはインデックス)mapping
arrayはfileBの行番号であり、これらのキーの値は次のようにfileAの行番号です。
配列mapping
は次のとおりです
Key Value
1 2
2 4
5 5
8 7
1
今私たちに必要なのは、上記のキー(、、、2
および5
FNR)と一致するfileBの行番号を読むことです。8
したがって、次のようにします。
NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };
さて、今価値はいくらですかmapping[FNR]
?mapping
上記の配列を確認すると、次のようになります。
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
したがって、配列の値をmapping
配列のキーとして使用します。これには以下が含まれます。hold
hold
Key Value
2 Argentina
4 Switzerland
5 Denmark
7 Colombia
最後のステップは、配列のキーをfileAの一致する行番号として使用することですhold
。その行番号が配列にある場合は、その行を配列の対応するキー値に置き換え、見つからhold
ない場合は行を印刷します。独自に (3 つのメタ演算子: condition? if-true : if-false
) 次のようにします。
{ print (FNR in hold)? hold[FNR]: $0; }