私は最初にawkとshellに触れ、shell / awkを使用して両方のファイルを同じレコードの行にマージする方法を知りたいと思います。 file1とfile2の名前の順序は異なる場合があります。同じレコードを持つ行だけをマージしたいと思います。助けてください。
file1.txt
Mary 68
Tom 50
Jason 45
Lu 66
file2.txt
Jason 37
Tom 26
Mary 74
Tina 80
mergefile.txt
Marry 68 74
Tom 50 26
Jason 45 37
awkを試しましたが、スクリプトの実行には少し時間がかかります。より高速で簡単なツールがあるかどうか疑問に思います。
cat file1.txt | while read line
do
score1=$( echo $line | awk '{print $2}');
name1=$( echo $line | awk '{print $1}');
cat file2.txt | while read l
do
score2=$( echo $l | awk '{print $2}');
name2=$( echo $l | awk '{print $1}');
if [[ $name1 == $name2 ]]
then
echo "$name1 $score1 $score2" >> mergefile
break
fi
done
done
答え1
awkを使用するには:
$ awk 'NR==FNR {a[$1] = $2; next} $1 in a {print $1, $2, a[$1]}' file2.txt file1.txt
Mary 68 74
Tom 50 26
Jason 45 37
ソートは不要で、2番目のファイルで指定された順序で出力されます。
説明する:
NR==FNR
最初の名前付きファイルからレコードを選択する正規の方法。{a[$1] = $2; next}
最初のフィールドのキーと2番目のフィールドの値で配列を入力します。$1 in a
最初のフィールドが最初のファイルにすでに表示されている場合。{print $1, $2, a[$1]}
2番目のファイルのキーと値、1番目のファイルの値を印刷します。
答え2
これは職業だと思います。join
、リレーショナルデータベースオペレータ
join <(sort file1.txt) <(sort file2.txt)
テスト
$ cat file1.txt
Mary 68
Tom 50
Jason 45
Lu 66
$ cat file2.txt
Jason 37
Tom 26
Mary 74
Tina 80
$ join <(sort file1.txt) <(sort file2.txt)
Jason 45 37
Mary 68 74
Tom 50 26
join
POSIXで指定された標準ツールです。
マニュアルjoin
ページには次のように記載されています。
The files file1 and file2 shall be ordered in the collating sequence of sort -b on the fields on which they shall be joined, by default the first in each line. All selected output shall be written in the same collating sequence.