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 个命令的结果与第一个命令不同吗?
答案1
awk 程序由对组成pattern {action}
,{action}
如果计算结果为 TRUE,则执行其中pattern
。如果pattern
省略,则默认假定为 TRUE,而如果{action}
省略,则默认操作为{print}
。
在
awk 'FS=","; OFS=","; {print $2, $3}' A.tsv
你有:
FS=","
指定,
为 的值的模式FS
,并且作为副作用计算 TRUE,触发默认操作{print}
模式
OFS=","
同样分配,
给,评估 TRUE 并第二次OFS
触发默认操作{print}
没有模式的操作
{print $2,$3}
,因此假定默认 TRUE 并触发该操作。然而,直到第一条记录已经被处理后才FS
被设置为,因此和都是空的(因为 awk 使用默认的空白来解析第一条记录,将整个记录分配给)。在后续记录中,它会打印预期的逗号分隔值。,
$2
$3
FS
$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