【问题标题】:awk, a field doesn't match but it should matchawk,一个字段不匹配,但它应该匹配
【发布时间】:2012-01-22 23:44:09
【问题描述】:

我有一个结构为记录列表的文件,其中字段分隔符是 \t。 我只想提取第二个字段是从 1 到 9 的数字的记录,但我的 awk 脚本不起作用。 awk 脚本是

cat file |awk -v FS="\t" '$2 ~ /[0-9]{1}/ {print $0;}'

或者这个

cat file |awk -v FS="\t" '$2 ~ /.{1}/ {print $0;}'  #because the second fields of my file have  all second fields as number

为什么这些脚本不起作用?正则表达式不是一个好的正则表达式吗?

【问题讨论】:

    标签: regex linux shell awk gawk


    【解决方案1】:

    更新

    即使使用区间 {1},您仍将匹配 23 之类的字段,因为 2 匹配单个数字。您真正想要使用的是锚点,而忘记了间隔:

    awk '$2 ~ /^[0-9]$/{print}' FS="\t" file
    

    问题在于使用间隔{1}awk 低于版本 4 不支持间隔。另一方面,gawk 会添加以下标志:--re-interval

    试试这个:

    awk --re-interval '$2 ~ /[0-9]{1}/{print}' FS="\t" file
    

    其他一些注意事项:

    1. 内置的 vars 如FS 可以在末尾分配而不需要-v
    2. 您可以只使用print 而不是print $0,因为这是它的默认行为
    3. cat 的无用使用。 awk 可以将文件作为参数,改为使用它

    【讨论】:

    • 我们不需要{print} 是吗? awk '$2 ~ /^[0-9]$/' FS="\t" file 不应该足够吗?
    • @SiegeX 非常感谢。使用 --re-interval 我已经解决了。感谢您的建议。
    • “awk 小于版本 4”这句话并没有多大意义。 awk 是一种语言,不是一种实现,而且只有一个版本。有很多实现,并且大多数都提供了一些扩展,但完全不清楚你的意思是w.r.t。第 4 版。
    • BusyBox awk 支持 {m,n} 间隔。 gawk v3 通过 --re-interval 或 --posix 开关支持它们,但不支持 --traditional 开关。 gawk v4 默认采用 --re-interval。
    【解决方案2】:

    如果你想确保第二个字段是个位数,你真的不需要正则表达式:

    awk '1 <= $2 && $2 <= 9 {print}'
    

    【讨论】:

    • 嗨@glenn,awk '1 &lt;= $2 &amp;&amp; $2 &lt;= 9' 不应该足够好吗?抱歉,我在上面也发布了类似的问题,因为我们没有打印任何特定的列,{print} 默认情况下会打印整行。抱歉还在学习:-)
    猜你喜欢
    • 2019-12-07
    • 2014-08-21
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多