cat file_1
my colour is red
my rose is red
my colour is blue
my rose id blue
cat file_2
red
blue
cat output_file should be
my colour is red
my colour is blue
ここで私は使う
cat file_2 | while read line;do cat file_1 | grep "$line" | head -1;done
pattern "red" and "blue"
ここでは、現在の値を含む最上位行を取得しようとしています。file_2
他の方法はありますか?as fast as possible
ループに時間がかかります。
答え1
コンストラクタを使用while
してパターンを繰り返し、次にfile2
with-m 1
を使用してgrep
最初の一致後に停止できますfile1
。
while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
-F
パターンを文字通り処理-m 1
grep
最初のゲーム後に終了
シェルループは通常それほど効率的ではありませんが、パターンリストが小さいため、この場合に便利です。
より速い選択肢、xargs
:
xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1
-P
より多くのパターンを得るには、より多くの並列プロセス()を使用してください。
例:
% while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
my colour is red
my colour is blue
% xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1
my colour is blue
my colour is red
答え2
file_2の行に一致するfile_1の最初の行を印刷するには:
$ awk 'FNR==NR{a[$0];next} {for (line in a) if ($0~line) {print; delete a[line]}}' file_2 file_1
my colour is red
my colour is blue
この方法では、各ファイルを一度だけ読み込みます。
どのように動作しますか?
FNR==NR{a[$0];next}
これは、file_2の各行を連想配列のキーとして保存します
a
。for (line in a) if ($0~line) {print; delete a[line]}
file_1の各行がarrayのキーと一致することを確認してください
a
。その場合は、その行を印刷してキーを削除します。