2015-04-28 58 views
1

对不起,但我从来没有问过这样的板子上的问题,请原谅经验不足。Awk与输入文件匹配和模式搜索

我想从输入文件中取一个字段,比如abc.txt中的两个字段,并在def.txt中匹配它。问题是我还需要在def.txt文件中匹配一个额外的模式。

对于exapmle,abc.txt中的字段2是“3”。我想在def.txt中搜索的模式是“efg”。我需要它返回所有符合pattern“efg”且包含“3”的行。

作为一个额外的约束,我希望它在达到某个值后停止搜索,比如说“END”。我已经用尽了精力在awk或其他变体中找到一个简单的单线程。

我对所有这些问题感到困惑,可以向新手寻求帮助吗?任何帮助表示赞赏,谢谢。

下面是代码,这是不工作: awk 'BEGIN { FS = " " } ;NR==FNR{a[$2]=++i;next} '{if ($5 in a) && ($0 ~ '/efg/')} {print $0}' abc.txt def.txt

我想实现三件事情:

  1. 匹配输入文件中的字段来def.txt领域

  2. 在def.txt中匹配一个模式

  3. 当遇到值时停止搜索以进行考试“完”。

希望一条线解决方案,如果可能的话,我只是太多的AWK初学者。

Sample Input 
Abc.txt 
1 
2 
3 
4 

Def.txt 
1 abc 
1 efg 
1 efg some more data 
END 
2 ghi 
2 efg 
2 efg some more data 
END 
3 jkl 
3 efg 
3 efg some more data 
END 

等等...

Expected Output 
1 efg 
1 efg some more data 
2 efg 
2 efg some more data 
3 efg 
3 efg some more data 

,并与任何帮助,以使其停止在到达 “END”。而不是浏览整个文件并打印1 efg,2 efg等的后续实例。

+0

abc.txt中的“3”与def.txt中的“efg”匹配并在两个文件中打印行?那两个文件都是空格分隔的吗?哪个文件包含“END”? – haifzhan

+0

你想用'/ efg'/'完成什么?无论如何,发布一些样本输入和期望的输出。 –

+0

@haifzhan - 我需要的文件来自def.txt文件。我正在寻找def.txt中与abc.txt中的“3”和def.txt中的“efg”匹配的行。 “END”语句也在我需要得到结果的文件中。对于缺乏细节感到抱歉,我正在学习如何有效发布。 – question33

回答

1

您的现有代码存在一些明显的问题。您提供了:

awk 'BEGIN { FS = " " } ;NR==FNR{a[$2]=++i;next} '{if ($5 in a) && ($0 ~ '/efg'/)} {print $0}' abc.txt def.txt 

我明白你要去哪里了。我想你的意思是:

awk 'NR==FNR{a[$2];next} $0=="END"{quit} $5 in a && /efg/' abc.txt def.txt 

显着的变化:

  • 单引号需要

    awk ' 
    
        # Step through first file, recording $2 in an array... 
        NR==FNR { 
        a[$2]; 
        next; 
        } 
    
        # Hard stop if we get a signal... 
        $0 == "END" { 
        quit; 
        } 
    
        # In the second+ file, test a condition. 
        $5 in a && /efg/ 
    
    ' abc.txt def.txt 
    

    当然,你可以通过删除注释和换行压缩成一个班轮这包装你的整个脚本。一个在开始,一个在结尾,没有“内部”。

  • 默认情况下awk会被空白分割,所以FS可能是不必要的(除非你在你的领域有选项卡,在这种情况下你可以把FS放回去)。
  • 您不需要增加计数器。在awk中,如果仅仅提供提及一个数组元素,它就是“创建”而没有内容,因此您可以使用像$5 in a这样的条件而不会浪费太多内存。
  • 额外的if声明已删除。 Awk需要condition { statement }模式。条件是一种条件,不管它是以这种格式还是在if之内。
  • 你的条件的第二个元素缩小到只是一个正则表达式。默认情况下,awk会将其表示为“这个正则表达式是否适用于当前输入行”。
  • print $0命令已被删除,因为如果未提供语句,则这是默认行为。
+0

这真是太棒了@ghoti,我会放弃它。 – question33

+0

我得到一个错误,说:'awk:致命的:无法打开源文件NR == FNR {a [$ 2];下一个; }用于阅读的&&/efg /'中的$ 5(没有这样的文件或目录)'我认为在第二条评论之后,我认为你的意思是让我自己格式化命令。我只是不确定。 – question33

+0

啊,傻了。从行中删除'-f'。我从我的答案中删除了它。 – ghoti