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


11

У меня есть 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

4
Формат примера не является файлом CSV, это файл с фиксированной шириной столбца. Вы можете уточнить вопрос или привести правильный пример.
AlexP

Ваш пример не является форматом CVS. Формат CVS есть abc.txt,errorstatus1,Fri Nov 11 02:00:09 2016. Я отредактировал ваш вопрос так, чтобы он соответствовал приведенному вами примеру. Не стесняйтесь откатываться, но учтите, что вам действительно нужно уточнить, что именно вы хотите - столбчатые значения или значения через запятую
Сергей Колодяжный

Ответы:


14

С paste:

paste - - - <file.txt

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

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

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

Чтобы упорядочить вывод, воспользуйтесь помощью 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

Здорово! Благодарность!! Но как распечатать эти значения в формате Excel. Я хочу, чтобы заголовки столбцов в листе Excel
назывались «

@ linux09 Создать CSV и импортировать с Excel:echo Filename,Status,Timestamp; paste -d ',' - - - <file.txt
heemayl

Brilliant! Работает как шарм. Большое спасибо
linux09

6

Вы можете использовать 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, с новой строкой после нее, поскольку она не соответствует первому блоку.

5

Там также rs(BSD R E сек Hape полезность):

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

3

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

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

В i, Nи ySED команды описаны здесь .


Отлично ... Не могли бы вы также кратко прокомментировать выражения, которые вы использовали? Спасибо!
Кампа

да, идеальный чувак
Кампа

1

Всегда есть возможность приготовить что-то для обработки текста с помощью 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.