输入数据有n列用“|”分隔比如下面的例子:
121|234234|5345|2342342342432423
1|2342|2|2342
234|23|343|34214222
如何找到每列的最大长度,稍后在输入的printf格式化中使用它,即使将来更改输入数据也会有效?
在命令中如下:
awk -F'|' '..... {printf“% - longestincol1 s% - longestincol2 s% - longestincol3 s%-s \ n”,$ 1 ,$ 2,$ 3,$ 4}'....
答案 0 :(得分:1)
<强>输入:强>
$ cat infile
121|234234|5345|2342342342432423
1|2342|2|2342
234|23|343|34214222
<强>输出:强>
使用 printf("%*s%s"
awk 'BEGIN{FS=OFS="|"}FNR==NR{for(i=1; i<=NF;i++)wd[i]=wd[i]>length($i)?wd[i]:length($i);next}{for(i=1; i<=NF; i++)printf("%*s%s",wd[i],$i,(i<NF?OFS:ORS))}' infile infile
121|234234|5345|2342342342432423
1| 2342| 2| 2342
234| 23| 343| 34214222
使用 printf("%-*s%s"
awk 'BEGIN{FS=OFS="|"}FNR==NR{for(i=1; i<=NF;i++)wd[i]=wd[i]>length($i)?wd[i]:length($i);next}{for(i=1; i<=NF; i++)printf("%-*s%s",wd[i],$i,(i<NF?OFS:ORS))}' infile infile
121|234234|5345|2342342342432423
1 |2342 |2 |2342
234|23 |343 |34214222
更好的可读性:
awk '
BEGIN{
FS=OFS="|"
}
FNR==NR{
for(i=1; i<=NF;i++)
wd[i]=wd[i]>length($i)?wd[i]:length($i);
next
}
{
for(i=1; i<=NF; i++)
printf("%*s%s",wd[i],$i,(i<NF?OFS:ORS));
}
' infile infile
<强>解释强>
Like C/C++指定为字符串
分配多少空间
*
宽度未在格式字符串中指定,而是作为 必须的参数前面的附加整数值参数 格式化。
printf("%*s",5,"")
与
相同printf("%5s", "");
答案 1 :(得分:0)
如果你只想要一个漂亮的打印输出,你可以使用column
例如
column -t -s'|' -o'|' file
但是,它并不完全符合您的printf
格式。它做左对齐。
如果你想用awk做,你可以应用至少两种方法:
你让awk经历一次输入,在循环期间计算最大宽度,保存内存中的所有行。最后,END{...}
遍历数组进行打印。
首先让awk浏览文件,只计算max-width,然后保存到变量中。在第二步,做格式打印。
我没有给出工作代码,但我希望我能清楚地回答。当你下次遇到类似的问题时,它也会有所帮助。