2015-09-04 66 views
6

我有一个文件通过字段列表说a.txt和下面是它的内容:打印作为一个变量

bob 1 100    
lincoln 2 200 
chris 3 300   

文件内容之间用空格分隔。

使用awk,我可以访问每列。使用以下命令 打印由逗号分隔的第1和第3列:

cat a.txt | awk ' { print $1","$3} ' 

,我是成功的。

现在我想从另一个shell脚本动态地传递条件。通过说标准我的意思是 - $1","$3

我试过下面的命令,但它没有工作。

myvar="$1" 
awk -v a="$myvar" ' { print a } ' a.txt 

但这打印$1 3倍有三排在a.txt

如何通过这种方式将awk的列表传递给awk?

+0

'“$ 1”'意味着你的shell脚本的第一个参数。你怎么称呼你的剧本? '脚本“1”'?如果'a'为'1',则应该打印'$ a' – Kent

+0

“$ 1”,“$ 3” - 这部分需要动态传递 - 以及分隔符。比如说,如果我有5列,我应该可以发送像1美元,2美元,3美元,4美元,5美元即1和2,4和5分开的逗号和休息 - 我会从另一个文件传递模式作为参数awk命令将在不同的文件 –

回答

6

这里的问题是,在变量$你传递给AWK字面解释 - 它不能用于指代特定的领域。

单个字段,你可以使用这样的事情:

awk -v field=1 '{ print $field }' file 
bob 
lincoln 
chris 

对于多个领域,这是一个有点复杂:

awk -v fields="1 3" 'BEGIN{ n = split(fields,f) } 
    { for (i=1; i<=n; ++i) printf "%s%s", $f[i], (i<n?OFS:ORS) }' file 
bob 100 
lincoln 200 
chris 300 

字段列表作为一个字符串传递,它被分成一个数组。然后使用printf输出每个字段,然后使用输出字段分隔符OFS或输出记录分隔符ORS,然后使用printf循环阵列,具体取决于它是否是最后一个字段。 要使用逗号分隔字段,可以将-v OFS=,作为选项通过。

+0

我很高兴我找到了我的问题的答案。有没有什么办法可以在多个文件的情况下添加分隔符到输出中 –

+0

是的,你可以将'OFS'设置为其他的东西比'awk -v OFS ='默认的空间' –

+0

“$ 1”,“$ 3” - 这部分实际问题需要动态传递 - 以及分隔符。 5栏,我应该能够发送像1美元,2美元,3美元,4美元,5美元即1和2,4和5分开逗号和休息的东西。 “。我将从另一个文件传递模式作为参数。而awk命令将在另一个文件上。我没有做到这一点。 –

3

您需要将分隔字符串传递给awk,并在awk的内部使用split分隔该分隔符。

像这样的东西应该工作:

awk -v search='1,3' 'BEGIN{split(search, a, ",")} 
       {f=""; for (i=1;i in a;i++) {printf "%s%s", f, $a[i]; f=OFS} print ""}' file 

输出:

bob 100 
lincoln 200 
chris 300 
+0

谢谢@TomFenech,我编辑它。不知何故''lenght'适用于BSD(OSX)awk – anubhava

+1

或捕获长度时分裂' len = split(...)' – karakfa

2

替代awk解决方案使用cut已通过逗号分隔列表接受字段位置。

cols="1,3"; cut -d" " -f"$cols" a.txt 

为逗号分隔输出管​​3210或使用--output-delimiter=","切选项。

注意,这会给你灵活地指定输入作为封闭或开放的范围,如1-32-