有没有办法column
对通过管道传入的数据进行类似过滤?
我正在寻找一种方法来执行类似的操作column -t
,但无需等待输入结束,因此它可以用于通过管道传输的实时数据。我知道我可以强制使用固定宽度的列awk
,但是每次格式更改时都需要太多设置。
PS:我认为模仿column -x
不完整的数据是不可能的。我还认为column -t
不可能在不完整的数据上完美地复制。如果解决方案首先输出较窄的列,然后随着更多行到达而扩展它们,那就可以了。
编辑:示例说明这不是缓冲问题:
yes something | cat -n | tr -s '\t' ' ' | column -t
答案1
整个要点column -t
是,它根据每列中每个字段的最大值自动对齐列中的字段。
如果您的输入包含
a b
a b
a bc
它将输出:
a b
a b
a bc
如果您添加:
xxxxx b
线连接到输入,输出变为:
a b
a b
a bc
xxxxx b
column
需要阅读全部输入行来确定每列的宽度,并且在此之前无法开始输出任何内容。
解决这个问题的唯一方法是您知道或可以猜测每列的最大宽度。
例如,如果您知道字段永远不会大于 10 个单元格,您可以执行以下操作:
<input tr -s '[:blank:]' '[\t*]' | expand -t 12
将输出格式化为 12 单元大列。
(请注意tr
,包括 GNU 在内的某些实现tr
不支持多字节字符,而expand
包括 GNU 在内的某些实现expand
既不支持多字节字符,也不支持零宽度或双宽度字符)
对于列宽度动态适应新输入宽度的解决方案,您可以执行以下操作:
perl -Mopen=locale -MText::CharWidth=mbswidth -lae '
for (0..$#F) {$l = mbswidth$F[$_]; $l[$_] = $l if $l > $l[$_]}
print((map {sprintf "%-$l[$_]s ", $F[$_]} (0..$#F-1)), $F[$#F])'
例如,在 的输出上lorem -p 2 | fmt -w 40
,给出:
Rerum aut pariatur nihil
modi. Exercitationem ut
animi. Quibusdam dolores
voluptates pariatur vel
tempora. Adipisci expedita voluptate
dolores qui consequatur. Laboriosam
eum ea. Quasi ab qui harum
repudiandae consequatur quasi
Nobis quia nesciunt laudantium.
enim exercitationem
earum. Pariatur nesciunt
maiores natus nemo delectus. Ut
ad voluptatem. Consequatur sint
enim sequi aut est nihil. Et at
或者仅重新格式化前 3 列:
perl -Mopen=locale -MText::CharWidth=mbswidth -lne '
@F = /(\S+)\s+(\S+)\s+(\S+)\s*(.*)/;
for (0..$#F) {$l = mbswidth$F[$_]; $l[$_] = $l if $l > $l[$_]}
print((map {sprintf "%-$l[$_]s ", $F[$_]} (0..$#F-1)), $F[$#F])'
给予:
Sit earum voluptatem cum adipisci aut
commodi. Quia aut eaque rerum nihil
aperiam. Dolor quia illo et. Quasi
illum est aliquam consequatur maiores
voluptatibus. Optio consectetur aliquid
Aspernatur omnis ex dolor nemo delectus
sit quia ut. Voluptatum voluptatibus
suscipit vel quos. Quo a at et non
cumque voluptate dolorum nostrum. Eos
ex est deleniti necessitatibus
assumenda provident culpa. Ut
sed et labore ullam voluptatum
impedit. Tempora delectus et rem dicta
debitis odit dignissimos.