我有两个文件。
file1.txt:
Afghans
Africans
Alaskans
...
其中file2.txt
包含网页上wget的输出,所以这是一个很大的混乱,但确实包含了第一个列表中的许多单词。
Bashscript:
cat file1.txt | while read LINE; do grep $LINE file2.txt; done
这没有按预期工作。我想知道为什么,所以我在循环中回显了$ LINE变量并添加了一个睡眠1,所以我可以看到发生了什么:
cat file1.txt | while read LINE; do echo $LINE; sleep 1; grep $LINE file2.txt; done
终端中的输出看起来像这样:
阿富汗人
非洲人
阿拉斯加
阿尔巴尼亚
美国人
grep:中文:没有这样的文件或目录
:没有这样的文件或目录
阿拉伯人
阿拉伯人
阿拉伯人/东印度人 :没有这样的文件或目录
Argentinans
亚美尼亚
亚洲
亚洲印第安人
:没有这样的文件或目录
file2.txt:亚洲火影忍者 ......
所以你可以看到它终于找到了“亚洲”这个词。但为什么会说:
没有这样的文件或目录
有什么奇怪的事情或我在这里遗漏了什么吗?
答案 0 :(得分:5)
怎么样?
grep -f file1.txt file2.txt
答案 1 :(得分:3)
@OP,首先,按照建议使用dos2unix
。然后使用awk
awk 'FNR==NR{a[$1];next}{ for(i=1;i<=NF;i++){ if($i in a) {print $i} } } ' file1 file2_wget
注意:在循环中使用while循环和grep效率不高,因为对于每次迭代,都需要在file2上调用grep
。
@OP,粗略解释:
有关FNR和NR的含义,请参阅gawk manual。 FNR==NR{a[1];next}
表示将file1的内容转换为数组a
。当FNR不等于NR(这意味着现在读取第二个文件)时,它将检查文件中的每个单词是否在数组a
中。如果是,打印出来。 (for循环用于迭代每个单词)
答案 2 :(得分:2)
使用更多引号并少用cat
while IFS= read -r LINE; do
grep "$LINE" file2.txt
done < file1.txt
答案 3 :(得分:1)
除了引用问题之外,您下载的文件还包含关闭read
的CRLF行结尾。在迭代之前使用dos2unix
转换file1.txt。
答案 4 :(得分:1)
尽管usng awk更快,但grep会以更少的工作量生成更多细节。因此,在发出 dos2unix 之后使用:
grep -F -i -n -f <file_containing_pattern> <file_containing_data_blob>
您将拥有所有匹配项+行号(不区分大小写)
至少可以找到file_containing_pattern中的所有单词:
grep -F -f <file_containing_pattern> <file_containing_data_blob>