1

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

2 回答 2

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

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

于 2014-01-23T19:17:35.933 回答
3

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

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

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

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

于 2014-01-23T19:19:25.783 回答