【问题标题】:awk: printing FILENAME once when criteria are met several times in a fileawk:在文件中多次满足条件时打印 FILENAME 一次
【发布时间】:2014-04-09 02:13:12
【问题描述】:

我有一系列文件,想知道哪些文件符合特定标准(例如,$1 == "ice" && $2 == "cream")。在同一个文件中多次满足此标准。当满足此条件时,我希望 awk 打印一次文件名。

我希望我说清楚了。

【问题讨论】:

    标签: if-statement awk criteria


    【解决方案1】:

    试试这个(下一个文件是 GNU 扩展):

    awk '$1=="ice" && $2=="cream"{print FILENAME;nextfile}'  file1 file2 file3
    

    或者如果你没有 GNU:

    awk 'FNR==1{p=0} $1=="ice" && $2=="cream" && !p {print FILENAME;p=1}'  file1 file2 file3
    

    FNR==1 在每个文件的开头重置p 标志,然后当满足您的条件时,p 标志设置为1,因此文件名只出现一次。

    顺便说一句,你可能更喜欢这样的简单性:

    grep -l "^ice.*cream" file*
    

    它不完全相同,但非常相似。

    接受后编辑

    这是另一种可能更优雅的可能性。它将匹配文件的名称保存在数组names[] 中,并在末尾打印数组names[] 的键。

    awk '$1=="ice" && $2=="cream" {names[FILENAME]++} END{for(i in names)print i}'
    

    【讨论】:

    • exit 这里会这样做,它只会打印找到的第一个文件名。如果他喜欢所有带有ice 和cream 的文件,它将失败。在 grep 中使用正则表达式,如果行在 ice 之前有 cream 将失败
    • 带有END 部分的第二个版本仅在命中位于多个文件中时才打印最后一个文件。
    • @Jotne 我假设他在奶油之前吃冰,因为他检查 1 美元的冰块和 2 美元的奶油。
    • 你是对的,但是 grep 也会为这一行提供命中 my cold ice cream
    • 确实!这就是为什么我说它“非常相似”。
    【解决方案2】:

    awk 应该这样做

    awk '$1 == "ice" && $2 == "cream" {print FILENAME}' *
    

    要获取行号和行信息,您可以使用:

    awk '$1 == "ice" && $2 == "cream"  {print NR,$0,"->",FILENAME}' *
    

    另一个版本:

    awk '/^ice cream/ {print NR,$0,"->",FILENAME}' *
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 2017-02-09
      • 2021-12-04
      • 1970-01-01
      相关资源
      最近更新 更多