Unix 我如何从与file2匹配的file1中grep内容,并将它们按file2的顺序排列

Unix 我如何从与file2匹配的file1中grep内容,并将它们按file2的顺序排列,unix,grep,Unix,Grep,我有file1.txt,内容如下: rs002 rs113 rs209 rs227 rs151 rs104 rs113 113 rs002 002 rs227 227 rs209 209 rs104 104 rs151 151 我有file2.txt,内容如下: rs002 rs113 rs209 rs227 rs151 rs104 rs113 113 rs002 002 rs227 227 rs209 209 rs104 104 rs151

我有
file1.txt
,内容如下:

rs002
rs113
rs209
rs227
rs151 
rs104
rs113   113
rs002   002
rs227   227
rs209   209
rs104   104
rs151   151
我有
file2.txt
,内容如下:

rs002
rs113
rs209
rs227
rs151 
rs104
rs113   113
rs002   002
rs227   227
rs209   209
rs104   104
rs151   151
我想获取与
file1.txt
中的记录相匹配的
file2.txt
行,我尝试了:

grep -Fwf file1.txt file2.txt 
输出如下:

rs113   113
rs002   002
rs227   227
rs209   209
rs104   104
rs151   151
rs002   002
rs113   113
rs209   209
rs227   227
rs151   151
rs104   104
这将提取所有匹配行,但它是按照
file2.txt
中的出现顺序进行的。在从
file1.txt
维护订单的同时,是否有方法提取匹配的记录?所需的输出如下:

rs113   113
rs002   002
rs227   227
rs209   209
rs104   104
rs151   151
rs002   002
rs113   113
rs209   209
rs227   227
rs151   151
rs104   104
这应该会有所帮助(但对于大投入来说不是最佳选择):

一种(不太优雅的)解决方案是循环使用
file1.txt
,并为每一行查找匹配项:

while IFS= read -r line; do
    grep -wF "$line" file2.txt
done < file1.txt
如果您知道每一行最多只出现一次,则可以通过告诉grep在第一次匹配后停止来加快速度:

grep -m 1 -wF "$line" file2.txt
据我所知,这是一个GNU扩展


请注意,在一个文件上循环以对每个循环中的另一个文件执行某些处理通常是一个问题,因此,这可能只适用于足够小的文件,因为找到更好的解决方案比使用此解决方案处理它们花费的时间更长。

这对于
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

从文件2创建sed命令文件

 sed 's#^\([^ ]*\)\(.*\)#/\1/ s/$/\2/#' file2 > tmp.sed
 sed -f tmp.sed file1
这两行可以组合在一起以避免tmp文件

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

sed-f您是否尝试过反转参数-
grep-Fwf file2.txt file1.txt
@adarshr,但这不起作用。这个grep命令的作用基本上是使用第一个文件作为您要查找的模式,第二个文件作为您要查找模式的文件。据我所知,仅仅使用grep命令是无法欺骗排序顺序的。也许awk或comm能帮上忙(不确定)。@adarshr尝试反转文件,但正如用户——randombee所说,第一个文件是一个具有特定模式的文件,我们希望第二个文件在分组时遵循该模式。我将在达到15%时回来投票赞成!发布这样一个解决方案是有危险的——新手可能会认为这是正确的方法,而不仅仅是一个有趣的轶事。reneesummer请按照Benjamin的建议阅读,然后接受,我相信Benjamin会同意这是正确的解决方案。请使用
“$line”
处理超过1个单词的行。在许多问题上,这是完全错误的方法。看见