使用特定输出字段分隔符打印特定列

使用特定输出字段分隔符打印特定列
cat A.tsv
1,a,d
2,b,e
3,c,f
$ awk -F ',' -v OFS="," '{print $2, $3}' A.tsv 
a,d
b,e
c,f
  • 我预计以下 4 个命令会给出与上面相同的结果:
$ awk 'FS=","; OFS=","; {print $2, $3}' A.tsv 
1,a,d
1,a,d
,
2,b,e
2,b,e
b,e
3,c,f
3,c,f
c,f
$ awk -F ',' 'OFS=","; {print $2, $3}' A.tsv 
1,a,d
a,d
2,b,e
b,e
3,c,f
c,f
$ awk -v OFS="," 'FS=","; {print $2, $3}' A.tsv 
1,a,d
,
2,b,e
b,e
3,c,f
c,f
$ awk -F ',' 'FS=OFS; {print $2, $3}' A.tsv 
1,a,d
a d
2,b,e
 
3,c,f

有人可以解释为什么最后 4 个命令的结果与第一个命令不同吗?

参考:shell脚本中awk -FS和awk -f之间的区别 - VoidCC

答案1

awk 程序由对组成pattern {action}{action}如果计算结果为 TRUE,则执行其中pattern。如果pattern省略,则默认假定为 TRUE,而如果{action}省略,则默认操作为{print}

awk 'FS=","; OFS=","; {print $2, $3}' A.tsv

你有:

  1. FS=","指定,为 的值的模式FS,并且作为副作用计算 TRUE,触发默认操作{print}

  2. 模式OFS=","同样分配,给,评估 TRUE 并第二次OFS触发默认操作{print}

  3. 没有模式的操作{print $2,$3},因此假定默认 TRUE 并触发该操作。然而,直到第一条记录已经被处理后才FS被设置为,因此和都是空的(因为 awk 使用默认的空白来解析第一条记录,将整个记录分配给)。在后续记录中,它会打印预期的逗号分隔值。,$2$3FS$1

您可能打算在记录处理开始之前在操作中分配FS=","OFS=","- 这是块的功能BEGIN

awk 'BEGIN{FS=","; OFS=","} {print $2, $3}' A.tsv

或者

awk -F ',' 'BEGIN{OFS=FS} {print $2, $3}' A.tsv

或者,您可以在文件名参数之前将变量赋值作为参数传递(如果您正在处理多个文件并希望为每个文件设置不同的字段分隔符,这有时很有用)

awk '{print $2, $3}' FS="," OFS="," A.tsv

相关内容