2014-01-23 34 views
1

我希望在变量“dc”中包含字段列表,例如'$ 1,$ 2'。 该变量传递给awk,但不能像我期望的那样工作。如何在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

做你问什么不添加大量的复杂的唯一方法是跳回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 

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

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 

也就是说,而非通过$1$2等从壳只是通过现场/列数。