如何传递变量与要在awk中打​​印的字段列表?

时间:2014-01-23 18:58:59

标签: bash variables printing awk fieldlist

我想在变量“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

2 个答案:

答案 0 :(得分:4)

在没有增加太多复杂性的情况下,做出你要求的唯一方法就是跳回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

它可能仍然不是最好的方法,但它可能会让你有所思考。

答案 1 :(得分:3)

在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等,只是传递字段/列号。