2016-08-10 4 views
0

Ich habe eine Textdatei mit Daten, die im folgenden Format angezeigt wird.awk - Druckausgabe im 3-Spalten-Format

apropos c 
awk nc 
chsh c 
date nc 
grep nc 
i3 nc 
ip6tables nc 

Ich versuche, diese Daten durch awk zu filtern, um ein 3-Spalten-Format zu erzeugen, ähnlich wie unten.

apropos   awk   chsh 
date    grep   i3 

Ich brauche nicht die zweite Spalte mit Informationen über die Datei, sondern möchte eine saubere und ausgerichtete Ausgabe der ersten Spalte. Ich habe den folgenden Code an anderer Stelle gefunden und ihn ein wenig modifiziert, um nur die erste Datenspalte auszugeben. Problem ist, dass es aufgrund der Verwendung von Tabs falsch ausgerichtet ist.

Ein bisschen mehr Forschung Ich fand die Verwendung der Breite über awk printf (dh. "% -10s"). Das einzige Problem ist, dass ich mir nicht ganz sicher bin, wie ich es in meinen Befehl integrieren kann, damit es das macht, was ich möchte. Jede Hilfe wäre willkommen, danke!

+0

Sie wollen 'ip6tables' nicht in der Ausgabe erscheinen, weil es nicht Teil eines Vielfachen von 3 ist? –

+0

Ich suche nach der ersten Spalte, die ausgegeben werden soll. Unabhängig davon, dass es ein Vielfaches von 3 ist. – barefly

+0

Dann bearbeiten Sie Ihre erwartete Ausgabe, um das zu zeigen. –

Antwort

4

Dies könnte sinnvoller sein, dass Sie als hart codierte einige beliebige Feldbreite wie 10:

$ awk '{ORS=(NR%3?FS:RS); print $1}' file | column -t 
apropos awk chsh 
date  grep i3 
ip6tables 

oder wenn Sie ip6tables von dem Ausgang fallen wollen wie in Ihrem Beispiel Eingabe/Ausgabe gezeigt:

$ awk '{rec = rec OFS $1} !(NR%3){print rec; rec=""}' file | column -t 
apropos awk chsh 
date  grep i3 

Wenn Sie dies nicht tun Rohr column und wollen nicht etwas willkürliche Zahl als die Feldbreite wählen, dann müssen Sie awk 2 Durchgänge der Eingabedatei, um die maximale Breite jeder Spalte, um herauszufinden, zuerst vor dem Drucken ng (siehe https://stackoverflow.com/a/38791539/1745001).

WRT das erste Beispiel - laufen alle UNIX-Tool auf Eingaben, die in einem Newline endet nicht auf undefinierten Verhalten gemäß der Spezifikation POSIX setzt also, wenn Ihr column eine Warnung gibt, wenn nach ip6tables eine fehlende Newline gibt es dann hinzufügen:

$ awk '{ORS=(NR%3?FS:RS); print $1} END{if (NR%3) printf "%s", RS}' file | column -t 
apropos awk chsh 
date  grep i3 
ip6tables 
+1

Dies funktionierte wie beabsichtigt. Gibt es eine Chance, dass ich einen Überblick darüber bekomme, wie deine awk-Anweisungen funktionieren? Ich lerne immer noch und bin immer am Verstehen interessiert. – barefly

+0

@barefly nachschlagen ORS, FS, RS und NR in den awk man-Seiten dann lesen Sie die Skripte (fügen Sie einige 'prints' wenn nötig, um zu sehen, was die Werte getestet werden/setzen) und Sie werden wahrscheinlich verstehen sie sofort, aber wenn nicht, lassen Sie mich wissen, wenn Sie irgendwelche spezifischen Fragen haben, und ich werde glücklich sein, sie zu beantworten. –

1

Sie können folgende awk | column Rohr verwenden:

awk '{sep=NR%3?OFS:ORS;printf "%s%s", $1, sep}END{if(NR%3)print ""}' a.txt \ 
    | column -t 

Hinweis: Da (zumindest) die BSD-Version der Spalte Befehl wird eine Warnung ausgegeben wird:

column: line too long 

und lassen Sie die letzte Zeile Wenn die Anzahl der Zeilen in der Liste kein Vielfaches der Spaltenanzahl ist, müssen Sie in diesem Fall nach dem letzten Element einen Zeilenumbruch drucken.

1

eine nicht-awk Lösung

$ cut -d' ' -f1 <file | paste - - - | column -t 

apropos awk chsh 
date  grep i3 
ip6tables 

oder mit pr

$ cut -d' ' -f1 <file | pr -3at 

apropos     awk      chsh 
date     grep     i3 
ip6tables