Linuxでこの出力ファイルを取得するより速い方法はありますか?

Linuxでこの出力ファイルを取得するより速い方法はありますか?
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してパターンを繰り返し、次にfile2with-m 1を使用してgrep最初の一致後に停止できますfile1

while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
  • -Fパターンを文字通り処理
  • -m 1grep最初のゲーム後に終了

シェルループは通常それほど効率的ではありませんが、パターンリストが小さいため、この場合に便利です。

より速い選択肢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。その場合は、その行を印刷してキーを削除します。

関連情報