文件内容
662293,211,sname in ('Market District', 'Express', 'Market', 'Market District Express')
62871,3506,RTANAME in ('ALLIANCE TA')
AWK命令使用
awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'
输出获得
in ('Market District', 'Express', 'Market', 'Market District Express')
in ('ALLIANCE TA')
你能告诉我如何使用AWK在输出中获得以下格式吗?
预期输出
sname in ('Market District', 'Express', 'Market', 'Market District Express')
RTANAME in ('ALLIANCE TA')
正如@RenaudPacalet已经提到的,您的脚本的主要问题不是设置FS,但您另外使用printf $i
而不是printf "%s", $i
,如果您的输入包含printf格式字符(如%s
),则会失败,并且您使用" "
作为输出字段分隔符而不是使用/print OFS。以下是如何使用任意awk正确编写代码的方法:
$ awk 'BEGIN{FS=OFS=","} {for (i=3; i<NF; i++) printf "%s%s", $i, OFS; print $NF}' file
sname in ('Market District', 'Express', 'Market', 'Market District Express')
RTANAME in ('ALLIANCE TA')
但是更习惯地在循环中打印一组值写成:
$ awk 'BEGIN{FS=OFS=","} {for (i=3; i<=NF; i++) printf "%s%s", $i, (i<NF ? OFS : ORS)}' file
sname in ('Market District', 'Express', 'Market', 'Market District Express')
RTANAME in ('ALLIANCE TA')
所以你不需要指定两次printf格式字符串(在你的情况下没有什么大不了的,但对于其他格式字符串可能是一个问题)-一次用于NF之前的所有内容,然后再用于NF。
在您的情况下,如果您使用awk,正确的做法是使用regexp删除前两个逗号分隔的字段:
$ awk '{sub(/([^,]*,){2}/,"")} 1' file
sname in ('Market District', 'Express', 'Market', 'Market District Express')
RTANAME in ('ALLIANCE TA')
更适合sed,因为它是一个简单的替换:
$ sed -E 's/([^,]*,){2}//' file
sname in ('Market District', 'Express', 'Market', 'Market District Express')
RTANAME in ('ALLIANCE TA')
但实际上,这是一份被裁掉的工作:
$ cut -d, -f3- file
sname in ('Market District', 'Express', 'Market', 'Market District Express')
RTANAME in ('ALLIANCE TA')
您只是忘记告诉awk
字段分隔符是逗号而不是默认的空格。此外,awk
字段从1开始编号,而不是0。因此,如果您想跳过前两个字段,则必须在i=3
:
for
循环。awk -F, '{for(i=3; i<NF; i++) printf "%s," $i; print $NF}'
注意,一旦您告诉awk
逗号是字段分隔符,printf $i
将不再打印逗号。这就是为什么,为了保存它们,我替换了你的:
printf $i " "
由:
printf "%s," $i
另一个选项,如果您的awk
支持这个(非posix),包括将所有字段移动两个位置,丢弃最后两个,并使用逗号也作为输出分隔符(OFS
):
awk -F, 'NF>=2{for(i=1;i<=NF-2;i++)$i=$(i+2);NF-=2}1' OFS=,
但它可能并不容易理解(最终的1
是一个奇怪的awk-ism,它与{print}
相同)。