Linux: Форматирование потока (канала) с колонкой? (неопределенный размер файла) - PullRequest
1 голос
/ 11 июня 2011

Я бы хотел отформатировать текстовое содержимое, которое получаю как поток stdout, используя column, но мне не удалось.Например, используя одну строку, все работает нормально:

$ 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 ]

1 голос
/ 18 апреля 2012

Я также обнаружил, что столбец разочаровывает невозможностью потоковой передачи, а код sdaau - неспособность измерять мои столбцы.Итак, вот решение обеих этих проблем.Может быть, не очень эффективно, но в любом случае это просто для отладки.У меня он есть в папке ~ / bin как pcol (не забудьте chmod + x it):

#!/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)
1 голос
/ 11 июня 2011

Ответа нет, потому что ваша вторая команда создает бесконечный цикл, а затем запрашивает, что после выполнения результат будет передан в столбец -t.Поскольку цикл никогда не завершится, столбец -t ничего не делает.Я не уверен, что вы пытаетесь выполнить, но вариант 2-й команды, который производит вывод с интервалом в одну секунду (что, я полагаю, вы хотите), таков:

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'
0 голосов
/ 11 июня 2011

ОК, благодаря ответам здесь, мне удалось подготовить скрипт на 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): [...]

Ура!

...