Как распечатать значения в текстовом файле в columnated файл с помощью сценария оболочки

У меня есть output.txt от выполнения сценария оболочки следующим образом:

abc.txt
errorstatus1
Fri Nov 11 02:00:09 2016
def.txt
errorstatus2.txt
Sat Nov 12 03:00:09 2016

Текстовый файл имеет многократные въезды линию за линией таким же образом. Я хочу распечатать эти значения в столбцы: Имя файла, Состояние и Метка времени следующим образом:

Filename      Status        Timestamp
abc.txt     errorstatus1   Fri Nov 11 02:00:09 2016
def.txt     errorstatus2   Sat Nov 12 03:00:09 2016
11
задан 13 December 2016 в 03:28

5 ответов

С paste:

paste - - - <file.txt

это произведет разделенное содержание файла новой строки как столбцы, и три вкладки разделили столбцы на строку.

Добавление заголовка:

echo Filename Status Timestamp; paste - - - <file.txt

К columnize вывод, возьмите справку от column:

{ echo Filename Status Timestamp; paste - - - <file.txt ;} | column -t

Пример:

% cat file.txt
abc.txt
errorstatus1
Fri Nov 11 02:00:09 2016
def.txt
errorstatus2.txt
Sat Nov 12 03:00:09 2016

% { echo Filename Status Timestamp; paste - - - <file.txt ;} | column -t
Filename  Status            Timestamp
abc.txt   errorstatus1      Fri        Nov  11  02:00:09  2016
def.txt   errorstatus2.txt  Sat        Nov  12  03:00:09  2016
14
ответ дан 23 November 2019 в 03:52

Существует также rs (BSD re утилита shape):

DESCRIPTION
     rs reads the standard input, interpreting each line as a row of blank-
     separated entries in an array, transforms the array according to the
     options, and writes it on the standard output.  With no arguments it
     transforms stream input into a columnar format convenient for terminal
     viewing.

, В частности,

     -e      Consider each line of input as an array entry.

Так

$ rs -e < file
abc.txt                   errorstatus1              Fri Nov 11 02:00:09 2016
def.txt                   errorstatus2.txt          Sat Nov 12 03:00:09 2016

или (для добавления заголовка)

$ { printf '%s\n' Filename Status Timestamp ; cat file ; } | rs -e
Filename                  Status                    Timestamp
abc.txt                   errorstatus1              Fri Nov 11 02:00:09 2016
def.txt                   errorstatus2.txt          Sat Nov 12 03:00:09 2016
5
ответ дан 23 November 2019 в 03:52

Для полноты вы можете сделать это также с sed:

sed -e '1iFilename\tStatus\tTimestamp' -e 'N;N;y/\n/\t/' file.txt
  • 1iFilename\tStatus\tTimestamp вставляет строку заголовка перед строкой 1
  • N;N читает еще два строк в буфер шаблонов, давая в общей сложности 3 строки, разделенные новыми строками
  • y/\n/\t/ заменяет все символы новой строки на вкладки в буфере шаблонов

y команды sed описаны здесь .

3
ответ дан 23 November 2019 в 03:52

Всегда возможно приготовить что-то для обработки текста с AWK или Perl и конечно Python, который является тем, что обеспечивает этот ответ.

Как острота:

python -c 'import sys;print "Filename\tStatus\tTimestamp"; lines=[l.strip() for l in sys.stdin];print "".join([l+"\n" if i%3 == 0 else l+"\t" for i,l in enumerate(lines,1) ])' < input.txt

, Поскольку многострочный сценарий

import sys
print "Filename\tStatus\tTimestamp"
lines=[l.strip() for l in sys.stdin]
print "".join([l+"\n" if i%3 == 0 else l+"\t" for i,l in enumerate(lines,1) ])

Основная идея здесь должен дать вход сценария через stdin (использующий перенаправление оболочки <, хотя канал может использоваться также). Сценарий использует вкладки для разделения полей, хотя пробелы могли использоваться также для более "подстроенного" вывода.

Демонстрационный вывод с помощью входного примера, обеспеченного OP:

$ python -c 'import sys;print "Filename\tStatus\tTimestamp";                                   
> lines=[l.strip() for l in sys.stdin];
> print "".join([l+"\n" if i%3 == 0 else l+"\t" for i,l in enumerate(lines,1) ])' < input.txt
Filename    Status  Timestamp
abc.txt errorstatus1    Fri Nov 11 02:00:09 2016
def.txt errorstatus2    Sat Nov 12 03:00:09 2016
1
ответ дан 23 November 2019 в 03:52

Вы могли использовать awk:

awk 'NR % 3 {printf "%s ", $0; next}1'

Вывод не мог бы быть столь же симпатичным:

$ awk 'NR % 3 {printf "%s ", $0; next} 1' input
abc.txt errorstatus1 Fri Nov 11 02:00:09 2016
def.txt errorstatus2.txt Sat Nov 12 03:00:09 2016

Вы могли использовать %s\t вместо этого для разделенного от вкладки вывода.

  • NR % 3 нуль (и ложь) для каждой третьей строки, таким образом, другие строки печатаются с пространством после них вместо новой строки. next только запускает следующее повторение.
  • Каждая третья строка печатается как есть из-за финала 1, с новой строкой после него, так как это не соответствует первому блоку.
6
ответ дан 23 November 2019 в 03:52

Другие вопросы по тегам:

Похожие вопросы: