使用AWK格式化数据



文件内容

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}相同)。

相关内容

  • 没有找到相关文章

最新更新