awk输出colum width到fixed

时间:2017-08-19 03:20:02

标签: bash shell awk

我想打印一个'echo'命令输出,其中的字段由'|'分隔到所有列具有固定相同宽度的列。因此,列数可能会有所不同,宽度应该是适用于所有列的全局设置。

示例输入

1234|sdan:active:running|sdax:active:running|sdbh:active:running|sdcv:active:running|sddf:active:running|sddp:active:running|Total paths 6 : OK
1235|sdc:active:running|sdm:active:running|sdw:active:running|sdbk:active:running|sdbu:active:running|sdce:active:running|Total paths 6 : OK
1236|sdam:active:running|sdaw:active:running|sdbg:active:running|sdde:active:running|sdcu:active:running|sddo:active:running|Total paths 6 : OK

5 个答案:

答案 0 :(得分:0)

这很容易通过修改每一行的每个字段来完成。以下成绩单显示了如何执行此操作:

pax> cat qq.awk
BEGIN { OFS = FS = "|" }
{   for (i = 1; i <= NF; i++) {
        $i = sprintf("%-12s", $i)
    }
    print
}

pax> cat qq.input
1234|sdan:active|sdcv:running|sddf:dead|sddp:active|3 paths:BAD
1235|sdc:active|sdm:active|sdw:running|sdbk:running|4 paths:OK
1236|sda:active|sdm:dead|2 paths:BAD

pax> awk -f qq.awk qq.input
1234        |sdan:active |sdcv:running|sddf:dead   |sddp:active |3 paths:BAD
1235        |sdc:active  |sdm:active  |sdw:running |sdbk:running|4 paths:OK
1236        |sda:active  |sdm:dead    |2 paths:BAD

重要的是sprint循环中的for(所述循环执行每个字段):

$i = sprintf("%-12s", $i);

这将每个字段替换为该字段的内容空间填充在右侧(至少)指定的宽度。

如果你想要一个单行而不是格式很好的脚本,你可以使用:

awk 'BEGIN{OFS=FS="|"}{for(i=1;i<=NF;i++){$i=sprintf("%-12s",$i)};print}' qq.input

答案 1 :(得分:0)

awk更容易,但可以使用sed

完成
width=12
printf -v blanks '%*s' "$width"
sed -rf <(echo "s/\|/${blanks}|/g; s/(.{${width}})[^|]*\|/\1|/g") input.txt

答案 2 :(得分:0)

假设:

$ cat file
1234|sdan:active|sdax:active|sdbh:active|sdcv:active|sddf:active|sddp:active|Total paths 6 : OK
1235|sdc:active|sdm:active|sdw:active|sdbk:active|sdbu:active|sdce:active|Total paths 6 : OK
1236|sdam:active|sdaw:active|sdbg:active|sdde:active|sdcu:active|sddo:active|Total paths 6 : OK

这是一个awk,它会打印w值的较长值或该字段中字符串长度的所有字段:

$ awk 'BEGIN{OFS=FS="|"; w=8}
 {for (i=1;i<=NF;i++) printf "%-*s%s", w, $i, i==NF ? ORS : OFS}' file
1234    |sdan:active|sdax:active|sdbh:active|sdcv:active|sddf:active|sddp:active|Total paths 6 : OK
1235    |sdc:active|sdm:active|sdw:active|sdbk:active|sdbu:active|sdce:active|Total paths 6 : OK
1236    |sdam:active|sdaw:active|sdbg:active|sdde:active|sdcu:active|sddo:active|Total paths 6 : OK

如果要剪切较长的字段以适合固定宽度:

$ awk 'BEGIN{OFS=FS="|"; w=11}
     {for (i=1;i<=NF;i++) printf "%-*s%s", w, substr($i,1,w), i==NF ? ORS : OFS}
     ' file
1234       |sdan:active|sdax:active|sdbh:active|sdcv:active|sddf:active|sddp:active|Total paths
1235       |sdc:active |sdm:active |sdw:active |sdbk:active|sdbu:active|sdce:active|Total paths
1236       |sdam:active|sdaw:active|sdbg:active|sdde:active|sdcu:active|sddo:active|Total paths

如果要浏览文件以获得适合所有字段的宽度,请使用该字段打印固定宽度的所有字段:

$ awk 'BEGIN{OFS=FS="|"}
       NR==FNR {for (i=1;i<=NF;i++) w=length($i)+1>w ? length($i)+1 : w; next}
               {for (i=1;i<=NF;i++) printf "%-*s%s", w, $i, i==NF ? ORS : OFS}
     ' file file
1234               |sdan:active        |sdax:active        |sdbh:active        |sdcv:active        |sddf:active        |sddp:active        |Total paths 6 : OK 
1235               |sdc:active         |sdm:active         |sdw:active         |sdbk:active        |sdbu:active        |sdce:active        |Total paths 6 : OK 
1236               |sdam:active        |sdaw:active        |sdbg:active        |sdde:active        |sdcu:active        |sddo:active        |Total paths 6 : OK 

答案 3 :(得分:0)

您只能使用column,如下所示:

$ column -s '|' -o '|' -t input.txt 
1234|sdan:active:running|sdax:active:running|sdbh:active:running|sdcv:active:running|sddf:active:running|sddp:active:running|Total paths 6 : OK
1235|sdc:active:running |sdm:active:running |sdw:active:running |sdbk:active:running|sdbu:active:running|sdce:active:running|Total paths 6 : OK
1236|sdam:active:running|sdaw:active:running|sdbg:active:running|sdde:active:running|sdcu:active:running|sddo:active:running|Total paths 6 : OK

答案 4 :(得分:-1)

你需要awk吗?

cat input.txt | tr '|' ' ' | rev | column -t | rev

如果您愿意,可以将tr替换为awk,但revcolumn -t会产生制表魔法。

Credit