Linux:使用列格式化流(管道)输出? (未确定的文件大小)

时间:2011-06-11 15:38:12

标签: linux formatting stream stdout

我想使用column格式化我作为stdout流获取的文本内容,但是我失败了。例如,使用单行,一切正常:

$ echo "1 12 123 1234 1 12 123 1234 " | column -t
1  12  123  1234  1  12  123  1234

..但是,如果我尝试模拟“无尽”的流:

$ while true; do echo "1 12 123 1234 1 12 123 1234 "; sleep 1; done | column -t
^C

...根本没有响应,直到用Ctrl-C退出。

(请注意,while只是为了模拟从设备中读取无休止的流,例如'cat /dev/ttyUSB0')

这让我相信,即使column默认接受标准输入,它也需要一个“完整”和完成的文件(即具有确定的文件大小)才能工作;而在“无尽”流的情况下,情况并非如此 - 因此它从不输出任何东西。

关于如何在此上下文中实现列格式化的任何建议?编辑:不一定必须是column程序;将文本格式化为列的任何其他内容都可以(但我担心,例如awk也需要一个完整的文件)...

提前致谢,
干杯!

3 个答案:

答案 0 :(得分:1)

没有响应,因为您的第二个命令创建了一个无限循环,然后询问一旦完成,结果将通过管道传递到列-t。由于循环永远不会终止,因此列-t不会执行任何操作。我不确定你要完成什么,但是第二个命令的变体确实以一秒的间隔产生输出(这就是我想要的):

while true; do echo "1 12 123 1234 1 12 123 1234 " | column -t; sleep 1; done

编辑: 我现在看到你在做什么。对于您的情况,您可以使用sed替换带有制表符的空格,只要数字位数不超过制表符大小,这会自动将您的数字与前一行对齐:

echo "1 12 123 1234 1 12 123 1234 " | sed 's/ /\t/g'

答案 1 :(得分:1)

我也发现列无法流式传输,而sdaau的代码无法测量我的列。所以这里解决了这两个问题。也许不是非常有效,但它只是用于调试,无论如何。我在我的〜/ bin文件夹中有pcol(确保chmod + x):

#!/usr/bin/env python
import sys

sep = ','
gutter = 2
for arg in sys.argv:
    if arg.startswith('-s'):
        sep = arg[2:]
    elif arg.startswith('-g'):
        gutter = int(arg[2:])

widths = []
while True:
    raw = sys.stdin.readline()
    line = raw.strip('\0').strip('\n')
    vals = line.split(sep)
    if len(vals) > len(widths):
        widths = [0] * len(vals)

    widths = [max(len(val) + gutter, width) for val, width in zip(vals, widths)]
    metaformat = '%%%ds' * len(widths)
    format = metaformat % tuple(widths)
    print format % tuple(vals)

答案 2 :(得分:0)

好的,感谢这里的回复,我设法制作了一个可以做到这一点的python脚本;显然,你必须知道(并在脚本中输入)a-priori列的格式;这是脚本columnizeline.py

#!/usr/bin/env python

import sys;

#below no work:
#print sys.stdin;
#for line in sys.stdin:
#   sline=line.split(' ')
#   print sline

while 1:
  next = sys.stdin.readline()
  ns = next.strip('\0').split(' ') # remove null char
  ns.pop() # remove the last entry in the list, it is '\n'
  #~ nextf = "%4s %4s %4s %4s %4s %4s %4s %4s" % (ns[0], ns[1], ns[2], ns[3], ns[4], ns[5], ns[6], ns[7])
  nextf=""
  nsc = ns[0:6] # first 6 elements only
  for nsi in nsc:
    nextf = "%s%5s" % (nextf, nsi)
  print nextf

......这是一个小测试:

$ while true; do echo "1 12 123 1234 1 12 123 1234 "; sleep 1; echo "100 1 123 12 1 12 123 1234 "; sleep 1; done | ./columnizeline.py 
   1   12  123 1234    1   12  123 1234
 100    1  123   12    1   12  123 1234
   1   12  123 1234    1   12  123 1234
 100    1  123   12    1   12  123 1234
   1   12  123 1234    1   12  123 1234
 100    1  123   12    1   12  123 1234
^CTraceback (most recent call last): [...]

干杯!