質問があります。アッ最初の列の値が一致すると、file1 の 2 つの列の値の一部を file2 の値に置き換えます。
例は次のとおりです。
私は持っています:
file1
A 2012 3 B 2012 4 C 2012 9 D 2012 E 2012 7 F 2012
file2
D 2007 12 F 2009 8 G 2000 4
希望の出力は、列1の値が一致したときです。次のように、列2と3の値をfile2の値に置き換えようとします。
- 希望の出力:
A 2012 3 B 2012 4 C 2012 9 D 2007 12 E 2012 7 F 2009 8
私はこのコードを使用しましたが、コードに問題があることを知っています。
awk 'BEGIN{FS=",";OFS="\t"}
FNR==NR{a[$1]=$2;b[$1]=$3; next}
FNR>=1{if(a[$1]){print $0 }else{print $1, a[$1], b[$1] }}
' file2 file1
このコードを使用したときに得た結果は次のとおりです。
A 2012 3
B 2012 4
C 2012 9
D 2012
E 2012 7
F 2012
これはと同じですfile1
。
誰かがこのコードの問題を説明したり、代替ソリューションを提案したりできますか?
答え1
問題には2つの側面があります。
- まず、入力フィールド区切り文字をに設定し、
,
入力をスペースで区切るように宣言します。これにより、現場作業が正しく機能しなくなります。入力がスペースで区切られている場合、入力行はデフォルトで「スペース」(つまり直接連続するスペースとタブの数)に分割されるため、実際にFS
設定する必要はありません。awk
- 2番目の問題はあなたの状況にあります
if (a[$1])
。現在の行の最初の列の値file1
が上にある場合、これは正確ですが、コードは実際に希望の値をfile2
変更するのではなく、変更されていない行を印刷します。file1
file2
print $0
また、フィールド区切り文字がから読み取ったのと同じ入力行を印刷するコマンドを使用して、その行をfile1
無視します。OFS="\t"
代わりに、以下を使用してください。
awk 'BEGIN{OFS="\t"}
NR==FNR{col2[$1]=$2;col3[$1]=$3;next}
FNR>=1{if ($1 in col2) {$2=col2[$1];$3=col3[$1]} else {$1=$1}}1' file2 file1
スペースが正しく置き換えられるように、実際の出力フィールド区切り文字を使用して行を再作成$1=$1
します。awk
\t