2013-02-25 104 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

我希望这有助于。

相关问题