2011-04-11 67 views
4

我有兩個文件。「while read do」和grep問題

file1.txt: 
Afghans 
Africans 
Alaskans 
... 

其中file2.txt包含網頁上的wget的輸出,所以這是一個大馬虎一塌糊塗,但包含了許多從第一列表中的單詞。

Bashscript:

cat file1.txt | while read LINE; do grep $LINE file2.txt; done 

如預期這沒有奏效。我不知道爲什麼,所以我附和了循環中的$行變量,並增加了睡眠1,所以我可以看到發生了什麼事:

cat file1.txt | while read LINE; do echo $LINE; sleep 1; grep $LINE file2.txt; done 

輸出看起來在終端看起來是這樣的:

阿富汗人
非洲人
阿拉斯加
阿爾巴尼亞
美國人
的grep:中國:沒有這樣的文件或目錄
:沒有這樣的文件或目錄
阿拉伯人
阿拉伯人
阿拉伯人/東印度人
:沒有這樣的文件或目錄
Argentinans
亞美尼亞
亞洲
印度人
:沒有這樣的文件或目錄
file2.txt:亞洲火影忍者
...

所以你可以看到它終於找到了「亞洲」這個詞。但爲什麼它說:

沒有這樣的文件或目錄

有什麼奇怪的事情發生還是我在這裏錯過了什麼?

+1

你只是問問是怎麼回事?或者你是否在尋求解決方案來編寫腳本? – MJB 2011-04-11 19:23:52

+0

我一定想知道爲什麼它不工作,但我打開通過一個工作版本的例子來學習,有意義嗎? – Kevin 2011-04-11 19:30:32

回答

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循環內部效率不高,因爲對於每一次迭代,你需要在文件2調用grep

@OP,原油說明: 有關FNR和NR的含義,請參閱gawk manualFNR==NR{a[1];next}表示將file1的內容存入數組a。當FNR不等於NR(這意味着現在讀取第二個文件)時,它將檢查文件中的每個單詞是否在數組a中。如果是,打印出來。 (for循環用於迭代每個單詞)

+0

工作!很酷。我可以麻煩你(簡單地)解釋一下嗎? Awk是我不瞭解的東西。我真的很想知道這是如何工作的。謝謝哥們! – Kevin 2011-04-12 01:15:23

+0

我爲你的好處簡單說一句,如果你想在上面學我,我不會反對...... – Kevin 2011-04-12 01:16:03

2

使用更多的報價,並使用更少的cat

while IFS= read -r LINE; do 
    grep "$LINE" file2.txt 
done < file1.txt 
+1

在這種情況下,'grep'將消耗所有用於'read'(也不是file2.txt)的輸入。 – 2011-04-11 19:27:42

1

還有報價問題,你已經下載的文件中包含有扔read關閉CRLF行結束。在迭代之前使用dos2unix轉換file1.txt。

+0

有趣。你已經爲我提供了2種解決方案。謝謝。但我仍然有點困惑。我剛剛創建了一個測試文件,其中包含file1.txt中的第一個項目。我使用了與「$ LINE」相同的命令,並且它沒有通過grep找到它。任何想法爲什麼? – Kevin 2011-04-11 19:39:44

+0

這個新文件使用什麼行結尾? – 2011-04-11 19:40:42

+0

編輯...(對不起,我誤讀)它應該是換行符,我用vi來製作它。這是否回答? – Kevin 2011-04-11 19:43:34

5

什麼

grep -f file1.txt file2.txt 
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>