Ich habe eine Datei, die Details zu VMs enthält, die in einem Hypervisor ausgeführt werden. Wir führen einen Befehl aus und leiten die Ausgabe in eine Datei um. Und die Daten sind im folgenden Format verfügbar.
Virtual Machine : OL6U5
ID : 0004fb00000600003da8ce6948c441bb
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U6
ID : 0004fb00000600003da8ce6948c441bc
Status : Running
Memory : 65536
Uptime : 17565 Minutes
Server : MyOVS2.vmorld.com
Pool : NON-HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U7
ID : 0004fb00000600003da8ce6948c441bd
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Diese Ausgabe unterscheidet sich von Hypervisor zu Hypervisor, da auf einigen Hypervisoren mehr als 50 VMS ausgeführt werden. Die obige Datei ist nur ein Beispiel aus dem Hypervisor, in dem nur 3 VMs ausgeführt werden. Daher wird erwartet, dass die umgeleitete Datei Informationen zu mehreren enthält (N Anzahl von VMs).
Wir müssen diese Details im folgenden Format mit awk / sed oder mit einem Shell-Skript erhalten
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U5 0004fb00000600003da8ce6948c441bb Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U6 0004fb00000600003da8ce6948c441bc Running 65536 17565 MyOVS2.vmworld.com NON-HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U5 0004fb00000600003da8ce6948c441bd Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
text-processing
sed
awk
IgniteLX
quelle
quelle
Antworten:
Wenn das zweimalige Durchlaufen der Datei kein (großes) Problem darstellt (speichert nur eine Zeile im Speicher):
Was für eine allgemeine Anzahl von Feldern wäre (was viele Durchgänge der Datei haben könnte):
Aber für eine wirklich allgemeine Transponierung wird dies funktionieren:
Und um es hübsch zu machen (mit Tab
\t
als Feldtrennzeichen):Der obige Code für eine allgemeine Transponierung speichert die gesamte Matrix im Speicher.
Das könnte ein Problem für wirklich große Dateien sein.
Update für neuen Text.
Um den neuen Text in der Frage zu verarbeiten, scheint es mir, dass zwei Durchgänge von awk die beste Antwort sind. Ein Durchgang, so kurz wie Felder vorhanden sind, druckt die Titel der Kopfzeilenfelder. Der nächste awk-Durchgang gibt nur Feld 2 aus. In beiden Fällen habe ich eine Möglichkeit hinzugefügt, führende und nachfolgende Leerzeichen zu entfernen (zur besseren Formatierung).
Die Umgebung
{ ... } | column -t -s "$(printf '%b' '\t')"
soll die gesamte Tabelle auf hübsche Weise formatieren.Bitte beachten Sie, dass die
"$(printf '%b' '\t')"
ersetzt werden könnte , mit$'\t'
in ksh, bash oder zsh.quelle
Wenn Sie das
rs
Dienstprogramm (Umformen) zur Verfügung haben, können Sie Folgendes tun:Dadurch wird das Ausgabeformat bis auf die dynamischen Spaltenbreiten genau wie in der Frage angegeben angegeben.
-T
Transponiert die Eingabedaten-z
Größe der Spalten entsprechend dem Maximum in jeder Spalte-c:
verwendet Doppelpunkt als EingabefeldtrennzeichenDies funktioniert für Tabellen beliebiger Größe, z.
rs
ist standardmäßig unter OS X (und wahrscheinlich auch auf anderen BSD-Computern) verfügbar. Es kann unter Ubuntu (und der Debian-Familie) installiert werden mit:quelle
EDIT: Erweiterbar auf eine beliebige Anzahl von Ausgabezeilen in einer einfachen Einzeiler-
for
Schleife:Ursprüngliche Antwort:
Sie können dies als Einzeiler mithilfe der
bash
Prozessersetzung tun :Die
-s
Option,paste
jede Datei einzeln zu verarbeiten. Das eingesetzte:
Trennzeichenpaste
wird durch die-s
Option "column
am Ende " "abgefangen" , um das Format durch Anordnen der Felder zu verbessern.Die
cut
Befehle in den beiden Prozessersetzungen ziehen das erste Feld bzw. das zweite Feld heraus.Ob die Eingabe Leerzeilen enthält oder nicht, spielt keine Rolle, da
column -t -s:
die Ausgabe unabhängig davon bereinigt wird. (Die in der Frage angegebene ursprüngliche Eingabe enthielt Leerzeilen, die jedoch inzwischen entfernt wurden. Der obige Befehl funktioniert unabhängig von Leerzeilen.)Eingabe - Inhalt der Datei mit dem Namen "Eingabe" im obigen Befehl:
Ausgabe:
quelle
Speichern Sie mit awk den Schlüssel und den Wert und drucken Sie sie am Ende aus.
Die laufen einfach
awk -f ./script.awk ./input.txt
quelle
quelle
Mit
gnu datamash
undcolumn
vonutil-linux
:Dies funktioniert mit mehr als zwei Spalten, setzt jedoch voraus, dass Ihre Eingabedatei keine Leerzeilen enthält. Mit leeren Zeilen dazwischen (wie in Ihrem ersten Eingabebeispiel) erhalten Sie eine Fehlermeldung wie:
Um zu vermeiden, dass Sie sie vor der Verarbeitung mit
datamash
folgenden Elementen zusammendrücken müssen :Andernfalls in diesem speziellen Fall (nur zwei Spalten) mit
zsh
und dasselbecolumn
:(${(f)"$(<infile)"})
liest die Zeilen in einem Array;${(j;:;)list[@]%:*}
verbindet (mit:
) das erste Feld jedes Elements und${(j;:;)list[@]#*:}
verbindet (wieder mit:
) das zweite Feld jedes Elements; diese werden beide gedruckt, zB die Ausgabe istwelches dann zu geleitet wird
column -t -s:
quelle
cat <(head -n 11 virtual.txt | cut -d: -f1) <(sed 's/.*: //' virtual.txt) | xargs -d '\n' -n 11 | column -t
Die Anzahl der Zeilen pro virtueller Maschine ist in diesem Fall fest codiert - 11. Zählen Sie sie besser vorher und speichern Sie sie in der Variablen. Verwenden Sie dann diese Variable im Code.
Erläuterung
cat <(command 1) <(command 2)
- Die<()
Konstruktion lässt diecommand
Ausgabe wie eine temporäre Datei erscheinen. Dahercat
verkettet zwei Dateien und Pipes es weiter.head -n 11 virtual.txt | cut -d: -f1
, gibt uns zukünftige Spaltenüberschriften. Der eine Eintrag für eine virtuelle Maschine besteht aus den ersten elf Zeilen. Derhead
Befehl wird verwendet, um ihn abzurufen. Dascut
teilt diesen Eintrag in zwei Spalten auf und druckt die einzige erste.sed 's/.*: //' virtual.txt
- gibt uns zukünftige Spaltenwerte.sed
Entfernt den gesamten nicht benötigten Text und hinterlässt nur Werte.xargs -d '\n' -n 11
. Jedes Eingabeelement wird durch einen Zeilenumbruch beendet. Dieser Befehl ruft Elemente ab und druckt sie mit 11 pro Zeile.column -t
- wird für hübsch gedruckte Displays benötigt. Es zeigt unsere Zeilen in Tabellenform an. Andernfalls hat jede Linie eine andere Breite.Ausgabe
quelle
Verwenden Sie
datamash
und seinetranspose
Option, um Zeilen und Spalten in einer Datei auszutauschen.Standardmäßig überprüft transponieren, ob die Eingabe die gleiche Anzahl von Feldern in jeder Zeile enthält, und schlägt ansonsten mit einem Fehler fehl. Sie können den strengen Modus deaktivieren, um fehlende Werte durch zuzulassen
--no-strict
Sie können auch den Füllwert
--filler
für fehlende Felder festlegen:abgeleitet von
datamash manual
quelle
Wenn sich Ihre Daten in separaten Dateien in einem Verzeichnis befinden, können Sie Folgendes verwenden:
Möglicherweise müssen Sie die Anzahl der
\t
(Tab-) Zeichen in derprintf
Zeile massieren , wenn Ihre variablen Werte unterschiedlich lang sind.quelle