将实时数据格式化为列(管道)

将实时数据格式化为列(管道)

有没有办法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.

相关内容