2013-02-25 137 views
9

我用下面的shell腳本找到一個文件的內容到另一個:找到一個文件的內容到UNIX Shell腳本另一個文件

#!/bin/ksh 
file="/home/nimish/contents.txt" 

while read -r line; do 
    grep $line /home/nimish/another_file.csv 
done < "$file" 

我執行腳本,但它不顯示來自csv文件的內容。我的contents.txt文件中包含的數字,如"08915673""123223"也存在於csv文件中。我有什麼不對嗎?

+2

考慮編輯您的問題,以包含每個文件中的2行以及給定這些輸入的預期輸出。祝你好運。 – shellter 2013-02-25 04:20:18

+1

上面的腳本不使用'file'變量,而是在那裏記錄名稱。嘗試'while read -r line <$ file; do'。也就是說,'ksh'糟透了,我還沒有檢查它使用'-r'來確定它是否會起作用。此外,即使csv文件中的行具有其他前導或尾隨數字,grep也會期望正則表達式並匹配任何包含數字的值:您可能需要'grep -w'或類似的語句。 – 2013-02-25 04:47:40

回答

27

grep本身能夠這樣做。簡單地使用該標誌-f

grep -f <patterns> <file> 

<patterns>是包含在每行一個圖案的文件;而<file>是要在其中搜索內容的文件。

請注意,要強制grep要考慮每行一個模式,即使每行的內容看起來像正則表達式,也應該使用標誌-F, --fixed-strings

grep -F -f <patterns> <file> 

如果你的文件是一個CSV,如你所說,你可以這樣做:

grep -f <(tr ',' '\n' < data.csv) <file> 

作爲一個例子,考慮文件 「a.txt中」,用下面幾行:

alpha 
0891234 
beta 

現在,文件 「b.txt」,用線:

Alpha 
0808080 
0891234 
bEtA 

以下命令的輸出是:

grep -f "a.txt" "b.txt" 
0891234 

你不需要在所有for -loop這裏; grep本身提供此功能。


現在使用的文件名:

#!/bin/bash 
patterns="/home/nimish/contents.txt" 
search="/home/nimish/another_file.csv" 
grep -f <(tr ',' '\n' < "${patterns}") "${search}" 

您可以更改','你在你的文件有分隔符。

+0

所以如果我替代 = $行將grep -f工作? – 2013-02-25 03:03:28

+0

所以使用grep -f它給出的錯誤爲「.rep:0652-033無法打開:」 – 2013-02-25 03:06:14

+0

那麼,問題似乎與文件路徑。你確定路徑是正確的嗎?嘗試用雙引號包含文件名。你是如何執行的。請在下一條評論中添加您嘗試運行的命令行。 – Rubens 2013-02-25 03:07:59

2

另一種解決方案:

  • 使用awk,創建你自己hash(例如ahash),全部由自己控制。
  • 替換$0 to $i,你可以匹配你想要的任何字段。

awk -F"," ' 
{ 
    if (nowfile==""){ nowfile = FILENAME; } 

    if(FILENAME == nowfile) 
    { 
    hash[$0]=$0; 
    } 
    else 
    { 
     if($0 ~ hash[$0]) 
     { 
      print $0 
     } 
    } 
} ' xx yy 
1

我不認爲你真的需要一個腳本來執行你想要做什麼。

一個命令就足夠了。在我的情況下,需要在一個CSV文件中列11的識別號碼(使用「;」作爲分隔符)

grep -f <(awk -F";" '{print $11}' FILE_TO_EXTRACT_PATTERNS_FROM.csv) TARGET_FILE.csv

我希望這有助於。

相關問題