基本上,我有一个带模式的文件,我希望在特定目录下的所有文本文件中搜索每一行。我也只想要完全匹配。许多文件已压缩。
但是,我还有一个条件。我需要模式文件中一行的前两列,以匹配所搜索的任何给定文本文件中一行的前两列。如果它们匹配,则我想要的输出是模式(整行),其后是找到匹配项的文本文件的所有名称以及它们的整个匹配行(不仅仅是前两列)。
输出,例如:
pattern1
file23:"text from entire line in file 23 here"
file37:"text from entire line in file 37 here"
file156:"text from entire line in file 156 here"
pattern2
file12:"text from entire line in file 12 here"
file67:"text from entire line in file 67 here"
file200:"text from entire line in file 200 here"
我知道grep可以获取一个输入文件,但是问题在于,它会获取模式文件中的每个模式,并在移至下一个文件之前在给定的文本文件中搜索它们,这使得上述输出更加困难。因此,我认为最好遍历文件中的每一行,打印该行,然后在多个文件中搜索该行,看看前两列是否匹配。
我想到了这个
cat pattern_file.txt | while read line
do
echo $line >> output.txt
zgrep -w -l $line many_files/*txt >> output.txt
done
但是使用此代码,它不会仅按前两列进行搜索。有没有办法为模式行和grep搜索通过的行指定前两列?
做到这一点的最佳方法是什么? grep以外的其他东西(例如awk)会更好用吗?还有其他类似问题,但是没有一个问题同时使用列作为搜索模式和搜索文件。
特征码文件中的几行:
1 5390182 . A C 40.0 PASS DP=21164;EFF=missense_variant(MODERATE|MISSENSE|Aag/Cag|p.Lys22Gln/c.64A>C|359|AT1G15670|protein_coding|CODING|AT1G15670.1|1|1)
1 5390200 . G T 40.0 PASS DP=21237;EFF=missense_variant(MODERATE|MISSENSE|Gcc/Tcc|p.Ala28Ser/c.82G>T|359|AT1G15670|protein_coding|CODING|AT1G15670.1|1|1)
1 5390228 . A C 40.0 PASS DP=21317;EFF=missense_variant(MODERATE|MISSENSE|gAa/gCa|p.Glu37Ala/c.110A>C|359|AT1G15670|protein_coding|CODING|AT1G15670.1|1|1)
搜索到的文件中的几行:
1 10699576 . G A 36 PASS DP=4 GT:GQ:DP 1|1:36:4
1 10699790 . T C 40 PASS DP=6 GT:GQ:DP 1|1:40:6
1 10699808 . G A 40 PASS DP=7 GT:GQ:DP 1|1:40:7
实际上两者都更大。
答案 0 :(得分:3)
听起来这可能就是您想要的:
awk 'NR==FNR{a[$1,$2]; next} ($1,$2) in a' patternfile anyfile
如果不是,那么请更新您的问题,以清晰,简单地说明您的要求,并提供简洁,可测试的样本输入和预期输出,以证明您的问题,并可以根据您的潜在问题进行测试。
如果anyfile
实际上是一个zip文件,那么您将执行以下操作:
zcat anyfile | awk 'NR==FNR{a[$1,$2]; next} ($1,$2) in a' patternfile -
如果使用的不是您要使用的命令,请用{\ x1}}替换zip文件中的文本。
答案 1 :(得分:0)
使用read
解析模式文件的列,并将锚添加到zgrep
模式:
while read -r column1 column2 rest_of_the_line
do
echo "$column1 $column2 $rest_of_the_line"
zgrep -w -l "^$column1\s*$column2" many_files/*txt
done < pattern_file.txt >> output.txt
read
能够将行解析为作为参数传递的多个变量,最后一个获取行的其余部分。它将在$IFS
内部字段分隔符的字符周围分隔字段(默认情况下,制表符,空格和换行符可以使用read
来替换while IFS='...' read ...
命令)。
使用-r
可以避免不必要的转义并使解析更加可靠,并且while ... do ... done < file
的性能要好一些,因为它可以避免不必要地使用cat
。由于while内所有命令的输出都被重定向,因此我也将重定向放在while
上,而不是每个单独的命令上。