【问题标题】:how to pass variable with list of fields to be printed in awk?如何通过要在awk中打​​印的字段列表传递变量?
【发布时间】:2023-03-24 06:29:01
【问题描述】:

我想要变量“dc”中的字段列表,例如“$1, $2”。 变量被传递给 awk,但没有按我预期的那样工作。

$ dc='$1, $2'          # variable with list of fields
$ fff="%-3s %-3s\n"    # format


$ echo "1 2 3 4 5"|awk -v fff="$fff" -v dc="$dc" '{printf fff, $1, $2}'     ### OK
1   2                      

$ echo "1 2 3 4 5"|awk -v fff="$fff" -v dc="$dc" '{printf fff, dc}'         ### NOT OK
  awk: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
          `%-3s %-3s
  '
            ^ ran out for this one

【问题讨论】:

    标签: bash variables printing awk fieldlist


    【解决方案1】:

    在不增加太多复杂性的情况下完成您要求的唯一方法是跳回 shell 以扩展 dc:

    $ echo "1 2 3 4 5"|awk -v fff="$fff" '{printf fff, '"$dc"'}'
    1   2
    

    但是在 30 多年的 UNIX 编程和 20 多年的使用 awk 中,我从来没有遇到过这样的情况,这将是最好的方法,所以如果你告诉我们更多关于你在做什么,我们可能会建议一个更好的选择。

    考虑一下 - 在一个设计良好的程序中,您应该能够在不改变接口或调用代码的情况下用 C 程序或其他东西替换整个 awk 脚本。使用您当前的方法,这显然是不可能的,因此您的软件是紧密耦合的,这是非常不可取的。

    这是一个替代示例:

    $ dc='1 2'
    $ fff="%-3s"
    $ echo "1 2 3 4 5"|awk -v fff="$fff" -vdc="$dc" 'BEGIN{n=split(dc,dcA)} {for (i=1; i<=n; i++) printf fff, $dcA[i] (i<n?FS:RS) }'
    1   2
    

    这可能仍然不是最好的方法,但也许它会给你一些思考。

    【讨论】:

      【解决方案2】:

      在 awk 中,您不能像尝试那样将 $1$2$3 等存储在字符串变量中。 $ 这里是一个运算符,它基于整数值n 表示输入中的n-th 列。

      如果你愿意,你可以这样做:

      echo "1 2 3 4 5"|awk -v fff="$fff" -v p="1" -v q="2" '{printf fff, $p, $q}'
      1   2  
      

      这不是从 shell 传递 $1$2 等,而是传递字段/列号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        • 2020-03-28
        • 2010-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多