【问题标题】:How can I use ":" as an AWK field separator?如何使用“:”作为 AWK 字段分隔符?
【发布时间】:2011-02-06 06:18:43
【问题描述】:

给定以下命令,

echo "1: " | awk '/1/ -F ":" {print $1}'

为什么 AWK 输出:

1:

?

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    “-F”是命令行参数,不是 AWK 语法。试试:

     echo "1: " | awk -F  ":" '/1/ {print $1}'
    

    【讨论】:

    • 这里无知的问题:/1/ 部分是告诉 awk 只处理包含数字 1 的行(或更准确地说是记录)对吗?
    • @rantsh awk 语法类似于(pattern){action}。如果pattern(主要是条件语句)为true,则执行action。如果pattern 不可用,则暗示true。这里的pattern/1/,它声明是正则表达式1 在当前记录$0 中匹配
    • 附带说明,如果分隔符是逗号,则需要在 awk 中添加 -v OFS="," 参数,以将其保留在输出中
    • 如何在 .awk 脚本中指出这一点?
    • @JoanSerrano 看看下面丹尼斯的回答就是这样做的
    【解决方案2】:

    如果您想以编程方式进行,可以使用FS 变量:

    echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'
    

    请注意,如果您在主循环而不是BEGIN 循环中更改它,它会影响读入的 next 行,因为当前行已经被拆分。

    【讨论】:

      【解决方案3】:

      您有多种方法可以将: 设置为分隔符:

      awk -F: '{print $1}'
      
      awk -v FS=: '{print $1}'
      
      awk '{print $1}' FS=:
      
      awk 'BEGIN{FS=":"} {print $1}'
      

      所有这些都是等效的,并且在给定示例输入“1:2:3”的情况下将返回1

      $ awk -F: '{print $1}' <<< "1:2:3"
      1
      $ awk -v FS=: '{print $1}' <<< "1:2:3"
      1
      $ awk '{print $1}' FS=: <<< "1:2:3"
      1
      $ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
      1
      

      【讨论】:

      • 哪个是首选方式?我假设BEGIN 语句的最后一个示例是最正确的(与整体awk 语法一致)。
      • @randomware 他们都很好。如果我使用文件来存储整个内容,我倾向于使用BEGIN,而-F 在单行中会派上用场。
      • 必须说第三种情况和其他所有情况都有细微的差别。示例:awk 'BEGIN{print split("foo:bar",a)}' FS=":" fileawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
      • 谢谢!我从清晰的例子中学习得最好。
      【解决方案4】:

      -Fawk 本身的参数:

      $echo "1: " | awk -F":" '/1/ {print $1}'
      1
      

      【讨论】:

      • 不用加冒号。
      【解决方案5】:

      您还可以使用正则表达式作为字段分隔符。下面将通过使用正则表达式将数字“10”设置为分隔符来打印“bar”。

      echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'
      

      【讨论】:

        【解决方案6】:

        没有必要写这么多。只需在 AWK 命令中使用 -F 选项输入所需的字段分隔符,并根据您提到的字段分隔符将要打印的列号分开。

        echo "1: " | awk -F: '{print $1}'
        1
        
        echo "1#2" | awk -F# '{print $1}'
        1
        

        【讨论】:

          【解决方案7】:

          AWK 用作文本解释器对整个文档逐行处理对每一行逐行处理。因此 $1, $2...$n 是对每一行字段的引用($1 是第一个字段,$2 是第二个字段,依此类推...)。

          您可以使用命令行下的“-F”开关或在带有“FS=...”的两个括号内定义字段分隔符。

          现在考虑the answer of Jürgen

          echo "1: " | awk -F  ":" '/1/ {print $1}'
          

          在字段上方,边界由“:”设置,因此我们有两个字段 $1 是“1”,而 $2 空白区域。之后是正则表达式“/1/”,它指示过滤器仅在解释器偶然发现包含此类表达式的行(我的意思是 1)时才输出第一个字段。

          “echo”命令的输出是包含“1”的一行,因此过滤器将起作用...

          在处理下面的例子时:

          echo "1: " | awk '/1/ -F ":" {print $1}'
          

          语法混乱,解释器选择忽略F部分“:” 并切换到默认的字段拆分器,即空白区域,因此输出“1:”作为第一个字段,不会有第二个字段!

          Jürgen 的答案包含了很好的语法...

          【讨论】:

            【解决方案8】:

            或者你可以使用:

            echo "1: " | awk  '/1/{print $1-":"}' 
            

            这是一个非常有趣的方程式。

            【讨论】:

            • /1/ 是什么意思?
            • 找到一个模式。在这种情况下为“1”
            • 为什么这是一个非常有趣的方程式?
            • 我认为这个技巧只适用于“:”之前的值是数字。回声“ab1:”| awk '/1/{print $1-":"}' 失败,打印一个 "0"
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-12-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多