“虽然读LINE做”和grep问题

时间:2011-04-11 19:22:12

标签: bash grep while-loop cat

我有两个文件。

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:亚洲火影忍者   ......

所以你可以看到它终于找到了“亚洲”这个词。但为什么会说:

  

没有这样的文件或目录

有什么奇怪的事情或我在这里遗漏了什么吗?

5 个答案:

答案 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 manualFNR==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>