So drucken Sie Werte in einer Textdatei mithilfe eines Shell-Skripts in eine Spaltendatei

11

Ich habe eine output.txt vom Ausführen eines Shell-Skripts wie folgt:

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

Die Textdatei enthält mehrere Einträge Zeile für Zeile auf dieselbe Weise. Ich möchte diese Werte wie folgt in Spalten drucken: Dateiname, Status und Zeitstempel:

Filename      Status        Timestamp
abc.txt     errorstatus1   Fri Nov 11 02:00:09 2016
def.txt     errorstatus2   Sat Nov 12 03:00:09 2016
linux09
quelle
4
Das Beispielformat ist keine CSV-Datei, sondern eine Datei mit fester Spaltenbreite. Möglicherweise möchten Sie die Frage klären oder ein korrektes Beispiel angeben.
AlexP
Ihr Beispiel ist kein CVS-Format. CVS-Format ist abc.txt,errorstatus1,Fri Nov 11 02:00:09 2016. Ich habe Ihre Frage so bearbeitet, dass sie mit dem von Ihnen angegebenen Beispiel übereinstimmt. Fühlen Sie sich frei, einen Rollback durchzuführen, aber bitte beachten Sie, dass Sie wirklich klären müssen, was genau Sie wollen - Spaltenwerte oder durch Kommas getrennte Werte
Sergiy Kolodyazhnyy

Antworten:

14

Mit paste:

paste - - - <file.txt

Dadurch werden der Inhalt der durch Zeilenumbrüche getrennten Datei als Spalten und drei durch Tabulatoren getrennte Spalten pro Zeile ausgegeben.

Hinzufügen der Kopfzeile:

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

Wenden Sie sich an column:

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

Beispiel:

% 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
heemayl
quelle
Cool! Vielen Dank!! Aber wie drucken Sie diese Werte im Excel-Format? Ich möchte die Spaltenüberschriften in der Excel-Tabelle als Dateinamenstatus und Zeitstempel und die Werte darunter
linux09
@ linux09 Erstellen Sie eine CSV und importieren Sie mit Excel:echo Filename,Status,Timestamp; paste -d ',' - - - <file.txt
heemayl
Brillant! Klappt wunderbar. Vielen Dank
linux09
6

Sie könnten awk verwenden:

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

Die Ausgabe ist möglicherweise nicht so hübsch:

$ 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

Sie können %s\tstattdessen eine durch Tabulatoren getrennte Ausgabe verwenden.

  • NR % 3ist Null (und falsch) für jede dritte Zeile, daher werden die anderen Zeilen mit einem Leerzeichen nach ihnen anstelle einer neuen Zeile gedruckt. nextStartet gerade die nächste Iteration.
  • Jede dritte Zeile wird aufgrund des Finales 1unverändert gedruckt , gefolgt von einer neuen Zeile, da sie nicht mit dem ersten Block übereinstimmt.
muru
quelle
5

Es gibt auch rs(BSD r e s hape Dienstprogramm):

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.

Im Speziellen,

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

So

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

oder (um den Header hinzuzufügen)

$ { 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
Steeldriver
quelle
3

Der Vollständigkeit halber können Sie dies sedauch tun mit :

sed -e '1iFilename\tStatus\tTimestamp' -e 'N;N;y/\n/\t/' file.txt
  • 1iFilename\tStatus\tTimestamp fügt die Kopfzeile vor Zeile 1 ein
  • N;N Liest zwei weitere Zeilen in den Musterpuffer und ergibt insgesamt 3 durch neue Zeilen getrennte Zeilen
  • y/\n/\t/ Ersetzt alle Zeilenumbrüche durch Tabulatoren im Musterpuffer

Die i, Nund ysed Befehle sind hier dokumentiert .

Digitales Trauma
quelle
Großartig. Könnten Sie auch kurz die von Ihnen verwendeten Ausdrücke kommentieren? Danke!
Campa
Ja, perfekter Typ
Campa
1

Mit AWK oder Perl und natürlich Python ist es immer möglich, etwas für die Textverarbeitung zu kochen, was diese Antwort bietet.

Als Einzeiler:

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

Als mehrzeiliges Skript

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

Die Grundidee hier ist, die Skripteingabe über stdin zu geben (unter Verwendung der Shell-Umleitung <, obwohl auch eine Pipe verwendet werden kann). Das Skript verwendet Registerkarten, um die Felder zu trennen, obwohl Leerzeichen auch für eine "fein abgestimmte" Ausgabe verwendet werden könnten.

Beispielausgabe anhand des von OP bereitgestellten Eingabebeispiels:

$ 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
Sergiy Kolodyazhnyy
quelle