2016-04-09 27 views
4

的順序我有file1.txt的內容:我如何可以grep從文件1匹配file2的內容並把他們的文件2

rs002 
rs113 
rs209 
rs227 
rs151 
rs104 

file2.txt的內容:

rs113 113 
rs002 002 
rs227 227 
rs209 209 
rs104 104 
rs151 151 

我想與中的記錄匹配的file2.txt的行,爲此我嘗試過:

grep -Fwf file1.txt file2.txt 

與輸出如下:

rs113 113 
rs002 002 
rs227 227 
rs209 209 
rs104 104 
rs151 151 

這提取所有匹配線,但它是在發生在file2.txt的順序。有沒有辦法在保持file1.txt的順序的同時提取匹配記錄?所需的輸出如下:

rs002 002 
rs113 113 
rs209 209 
rs227 227 
rs151 151 
rs104 104 
+0

請查看[editing-help](http://stackoverflow.com/editing-help)。 – Cyrus

+0

您是否嘗試過反轉參數 - 「grep -Fwf file2.txt file1.txt」 – adarshr

+0

@adarshr這是行不通的。這個grep命令的作用基本上是使用第一個文件作爲你正在尋找的模式,第二個文件作爲你尋找模式的文件。據我所知,你不能僅僅通過使用grep命令來欺騙排序順序。也許awk或comm可以幫助(不確定)。 – randombee

回答

-1

這應該幫助(但不會最適用於大輸入):

$ for line in `cat file1.txt`; do grep $line file2.txt; done 
+2

對於超過1個單詞的行,請使用'「$ line」'。 –

+0

完全錯誤的方法有很多問題。見http://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice –

2

一(amittedly不是很優雅)的解決方案是遍歷file1.txt,尋找一個匹配的每一行:

while IFS= read -r line; do 
    grep -wF "$line" file2.txt 
done < file1.txt 

這給輸出

rs002 002 
rs113 113 
rs209 209 
rs227 227 
rs151 151 
rs104 104 

如果你知道,每行最多隻發生一次,這可以通過告訴grep的加速位後的首場比賽停止:

grep -m 1 -wF "$line" file2.txt 

這是一個GNU擴展,因爲據我可以告訴。

請注意,循環一個文件以對每個循環中的另一個文件執行一些處理通常是sign that there is a much more efficient way to do things,所以這應該只用於足夠小的文件,因爲提出更好的解決方案需要比處理更長的時間他們與這個解決方案。

+0

非常感謝!這工作! – reneesummer

+0

一旦我達到15的聲望,我會回來投票是! – reneesummer

+0

,並且存在發佈類似解決方案的危險 - 新手可能會認爲這是正確的方法,而不僅僅是一個有趣的軼事。 reneesummer請閱讀http://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice按照本傑明的建議,然後接受[@ Thor的回答](http://stackoverflow.com/a/36524323/1745001),我相信本傑明會同意這是正確的解決方案。 –

2

這對於grep來說太複雜了。如果file2.txt並不大,也就是說,它能夠裝入內存,你或許應該使用awk

awk 'FNR==NR { f2[$1] = $2; next } $1 in f2 { print $1, f2[$1] }' file2.txt file1.txt 

輸出:

rs002 002 
rs113 113 
rs209 209 
rs227 227 
rs151 151 
rs104 104 
0

從文件2

sed 's#^\([^ ]*\)\(.*\)#/\1/ s/$/\2/#' file2 > tmp.sed 
sed -f tmp.sed file1 

創建一個sed命令文件這2行可以結合避免tmp文件

sed -f <(sed 's#^\([^ ]*\)\(.*\)#/\1/ s/$/\2/#' file2) file1 
相關問題