我会尽力为您翻译,您提供的内容是将一个长列重新格式化为三个逗号分隔的列,如下所示,使用 awk
或任何 Unix 工具。
输入:
Xaa
Ybb
Mdd
Tmmn
UUnx
THM
THSS
THEY
DDe
输出:
Xaa,Ybb,Mdd
Tmmn,UUnx,THM
THSS,THEY,DDe
我会尽力为您翻译,您提供的内容是将一个长列重新格式化为三个逗号分隔的列,如下所示,使用 awk
或任何 Unix 工具。
输入:
Xaa
Ybb
Mdd
Tmmn
UUnx
THM
THSS
THEY
DDe
输出:
Xaa,Ybb,Mdd
Tmmn,UUnx,THM
THSS,THEY,DDe
$ awk '{printf "%s%s",$0,NR%3?",":"\n";}' file
Xaa,Ybb,Mdd
Tmmn,UUnx,THM
THSS,THEY,DDe
对于每一行输入,这个程序会先输出该行内容,然后根据行号输出逗号或换行符。
其中最关键的部分是三目运算语句:
NR%3?",":"\n"
这将行号模以3。如果结果非零,则返回逗号。如果为零,则返回换行符。
假设文件中的行数是3的整数倍。如果不是,则我们可能希望确保最后一行有一个换行符。可以像Jonathan Leffler建议的那样完成此操作:
awk '{printf "%s%s",$0,NR%3?",":"\n";} END { if (NR%3 != 0) print ""}' file
awk 'NR==1{printf "%s",$0; next} {printf "%s%s",(NR-1)%3?",":"\n",$0;} END {print ""}' file
awk '{ printf("%s%s", pad, $1); pad = (NR%3 == 0) ? "\n" : "," } END { print "" }'
为了支持不使用\n
作为行终止符的平台,Ed Morton建议:
awk -v OFS=, '{ printf("%s%s", pad, $1); pad = (NR%3?OFS:ORS)} END { print "" }' file
有一个工具可以做到这一点。使用pr
pr -3ats,
xargs -n3 < file | awk -v OFS="," '{$1=$1} 1'
xargs
使用 echo
作为默认操作,$1=$1
强制重建 $0
。
只使用 awk,我会选择这个(与 @jonathan-leffler 和 @John1024 提出的类似)
{
sep = NR == 1 ? "" : \
(NR-1)%3 ? "," : \
"\n"
printf sep $0
}
END {
printf "\n"
}
END { if (NR%3 != 0) print ""}
是否有优点,以便至少使最后一行以换行符结束?修复以避免发出额外的尾随逗号更加困难(也就是说,如果文件长度不是三的倍数,则最后一行可能会读取为One,
或One,Two,
)。 - Jonathan Lefflerawk '{ printf("%s%s", pad, $1); pad = (NR%3 == 0) ? "\n" : "," } END { print "" }'
。这使用了“未初始化变量被视为空字符串”的属性。而print
总是输出一个换行符(我曾经尝试过print "\n"
,但最后得到了两个换行符;可以用printf "\n"
代替print ""
)。 - Jonathan Leffler+1
,但有几点需要注意 - 1)应该使用ORS
而不是"\n"
,这样它就可以在换行符为\r\n
的平台/应用程序上工作(而且更简洁),2)在某些 awk 上,未加括号的三元表达式会在某些情况下导致语法错误(例如,在 OSX awk 上尝试print 1>2?"foo":"bar"
),因此最好总是将其括起来(NR%3?",":ORS)
,甚至-v OFS=, ... (NR%3?OFS:ORS)
,以避免这个问题,并且在我的看法中,当三元表达式的开始/结束被这样分隔时,它可以提高清晰度。 - Ed Morton