【问题标题】:How to do a if else match on pattern in awk如何在awk中对模式进行if else匹配
【发布时间】:2025-12-05 03:55:02
【问题描述】:

我试过下面的命令:

awk '/search-pattern/ {print $1}'

上述命令的else部分如何写?

【问题讨论】:

    标签: shell awk grep


    【解决方案1】:

    Classic way:

    awk '{if ($0 ~ /pattern/) {then_actions} else {else_actions}}' file
    

    $0代表整个输入记录。

    Another idiomatic way 基于三元运算符语法selector ? if-true-exp : if-false-exp

    awk '{print ($0 ~ /pattern/)?text_for_true:text_for_false}'
    awk '{x == y ? a[i++] : b[i++]}'
    
    awk '{print ($0 ~ /two/)?NR "yes":NR "No"}' <<<$'one two\nthree four\nfive six\nseven two'
    1yes
    2No
    3No
    4yes
    

    【讨论】:

      【解决方案2】:

      一个简单的方法是,

      /REGEX/ {action-if-matches...} 
      ! /REGEX/ {action-if-does-not-match}
      

      这是一个简单的例子,

      $ cat test.txt
      123
      456
      $ awk '/123/{print "O",$0} !/123/{print "X",$0}' test.txt
      O 123
      X 456
      

      等价于上述,但不违反DRY principle

      awk '/123/{print "O",$0}{print "X",$0}' test.txt
      

      这在功能上等同于awk '/123/{print "O",$0} !/123/{print "X",$0}' test.txt

      【讨论】:

      • @EdMorton 那么最好的选择是什么? George's answer 中的 {print ($0 ~ /pattern/)?text_for_true:text_for_false} 方法?
      • @fedorqui 是的,如果“else”部分也是打印件(这也是我对这种情况的回答中的第三个选项)。否则我的答案中的第一个或第二个选项。
      • 最后一个建议(符合 DRY 原则的建议)应该包含一个 'next',如下所示: awk '/123/{print "O",$0;下一个}{print "X",$0}'
      【解决方案3】:

      根据您想在 else 部分中执行的操作以及有关脚本的其他内容,在以下选项之间进行选择:

      awk '/regexp/{print "true"; next} {print "false"}'
      
      awk '{if (/regexp/) {print "true"} else {print "false"}}'
      
      awk '{print (/regexp/ ? "true" : "false")}'
      

      【讨论】:

        【解决方案4】:

        awk 的默认操作是打印一行。鼓励您使用更惯用的 awk

        awk '/pattern/' filename
        #prints all lines that contain the pattern.
        awk '!/pattern/' filename
        #prints all lines that do not contain the pattern.
        # If you find if(condition){}else{} an overkill to use
        awk '/pattern/{print "yes";next}{print "no"}' filename
        # Same as if(pattern){print "yes"}else{print "no"}
        

        【讨论】:

          【解决方案5】:

          此命令将检查 $1 $2 和 $7-th 列中的值是否大于 1、2 和 5。

          !如果!我们在 awk 中声明的过滤器会忽略这些值。

          (您可以使用逻辑运算符和=“&&”;或=“||”。)

          awk '($1 > 1) && ($2 > 1) && ($7 > 5)'
          

          您可以使用“vmstat 3”命令监控您的系统,其中“3”表示新值之间有 3 秒的延迟

          vmstat 3 | awk '($1 > 1) && ($2 > 1) && ($7 > 5)'
          

          我用 USB 连接的硬盘之间的 13GB 副本对我的计算机施加压力,并在 Chrome 浏览器中滚动 youtube 视频。

          【讨论】: