ファイルが2つあり、最初の行は参照用のヘッダー行です。
file1
userId userContact parentId parentContact 200 0900200 100 - 201 0900201 100 - 300 0900300 101 -
file2
userId userContact parentId parentContact 100 0900100 100 - 101 0900101 100 -
4番目の列では、inをfile1
検索してofをfromに置き換える必要があるため、出力は次のようになります。$3
file1
$1
file2
$2
file2
$4
file1
output
userId userContact parentId parentContact 200 0900200 100 0900100 201 0900201 100 0900100 300 0900300 101 0900101
awk
より速いので好む。
答え1
使用join
(ソートされた入力ファイルが必要なので、ソートされた入力を渡しました)。
join -1 3 -2 1 -o 1.1,1.2,1.3,2.2 <(sort -k3 file1) <(sort file2)
200 0900200 100 0900100
201 0900201 100 0900100
300 0900300 101 0900101
を使用すると、Joinは-1 3
最初の入力ファイル(file1)のキーとして3番目の列を選択し、2番目の入力ファイル(file2)のキーとして1番目の列を-2 1
選択して-o
これらの列を出力します。<ファイル番号>.<列番号>。
入力内容がタブ区切りファイルの場合は、-t$'\t'
結合コマンドにも追加してくださいsort -k3 file1
。
ヘッダー行を印刷するには、head -n1 file1;
結合の前に追加します。
または以下を使用してくださいawk
。
awk 'NR==FNR{ parentId[$1]=$2; next }
FNR>1 { $4=parentId[$3] }1' file2 file1
答え2
$ awk 'NR==FNR { keep[$1] = $2 ; next};
FNR==1 {print;next};
{ $4 = keep[$3]; print }' file2 file1
userId userContact parentId parentContact
200 0900200 100 0900100
201 0900201 100 0900100
300 0900300 101 0900101
これはから読み取られ、file2
各行のフィールド2を名前付き配列に格納しますkeep
(フィールド1の値でインデックス付けされます)。読み取りが終わったらfile2
読み取りを開始しますfile1
。最初の行(ヘッダー行)を印刷してから、各後続の入力行に対してフィールド4を値に変更してkeep[$3]
印刷します。
スクリプトは、読んでいるかどうかを検出するためにfile2
テストします。NR==FNR
awk のFNR
変数には、現在のファイルの現在の行番号と、NR
これまでに読み込んだすべてのファイルの累積合計行番号が含まれます。したがって、FNRがNRと等しい場合は、最初のファイルを読み取ることができます(つまりfile2
、最初のファイル名引数としてリストされるべき理由です)。このテストがうまく機能しないかなり曖昧なケースがありますが、ほとんど(このテストを含む)には問題ありません。
入力フィールドまたは出力フィールドの区切り文字を変更する必要がある場合は、awkの-Fおよび-vオプションを使用できます。たとえば、-F'\t'
および/または-v OFS='\t'
。