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
while 迴圈需要時間
答案1
您可以使用while
建構來循環 from 的模式file2
,然後使用-m 1
withgrep
在第一次匹配後停止file1
:
while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
-F
從字面上對待模式-m 1
使grep
第一場比賽後退出
Shell 循環通常效率不高,但由於模式清單很小,因此在這種情況下是可用的。
更快的替代方案, 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_1 中與 file_2 中的行相符的第一行:
$ 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
。如果是,我們列印該行並刪除該密鑰。