
Wir können die letzte Spalte jeder Zeile in einer Datei ausdrucken, $NF
wenn wir die letzte Spaltennummer nicht kennen.
Ich habe jedoch ein Problem, da die letzte Spalte einen leeren Wert aufweist.
Zum Beispiel,Parsing who
-Befehl
$ who
root tty1 2018-01-25 09:36
root pts/0 2018-05-30 07:39 (192.168.1.134)
root pts/1 2018-05-28 23:12 (192.168.1.134)
root pts/2 2018-06-01 10:01 (192.168.1.188)
Ergebnis erhalten:
$ who | awk '{print $NF}'
09:36
(192.168.1.134)
(192.168.1.134)
(192.168.1.188)
erwartetes Ergebnis
(192.168.1.134) (192.168.1.134) (192.168.1.188)
Teilen Sie mir die Möglichkeiten mit, das erwartete Ergebnis in einem Einzeiler zu erzielen.
BEARBEITEN 1:Das obige Szenario ist nur ein Beispiel. Ich möchte das Trennzeichen nicht ändern, um das Ergebnis zu erzielen.
BEARBEITEN 2:nichts (eine leere Ausgabezeile) aus den Zeilen, die weniger Felder haben als das Maximum
Antwort1
Um nur die letzte Spalte mit den Zeilen auszugeben, die die maximale Spaltenanzahl aufweisen, können Sie Folgendes tun:
who | awk '
NF > max {max = NF; output = ""}
NF == max {output = output $NF ORS}
END {printf "%s", output}'
So geben Sie für jede Eingabezeile eine Zeile aus, die jedoch für Zeilen, die nicht die maximale Spaltenanzahl aufweisen, leer bleibt:
who | awk '
NF > max {max = NF}
{n[NR] = NF}
NF == max {last[NR] = $NF}
END {for (i = 1; i <= NR; i++) print n[i] == max ? last[i] : ""}'
Antwort2
Wenn Sie nur das letzte Feld aus den Zeilen mit den meisten Feldern benötigen, müssen Sie die Daten zweimal durchlesen: einmal, um die höchste Anzahl von Feldern zu ermitteln, und ein weiteres Mal, um die Felder auszudrucken. Nur einmal zu lesen reicht nicht aus: Jede Zeile könnte mehr Felder als die vorherigen haben, und es gibt keine Möglichkeit, das herauszufinden.
Mit awk
(beachten Sie, dass der Dateiname zweimal angegeben ist):
awk -vfields=0 'FNR==NR {if (NF > fields) fields=NF; next}
NF >= fields { print $NF } NF < fields {print ""}' file file
Wenn file
enthält
foo bar
one two three four
1 2 3
a b c d
Dadurch wird das vierte Feld gedruckt, oder es wird für Zeilen, die es nicht enthalten, leer gelassen:
vier D
Das funktioniert natürlich nicht mit einer Pipe, da musst du eine temporäre Datei verwenden.
Eine alternative Lösung könnte darin bestehen, die zu druckenden Felder zwischenzuspeichern, bis eine Zeile mit weiteren Feldern erscheint, wie inStéphanes Antwort.
Antwort3
Überprüfen Sie, ob das 5. Feld übereinstimmt \(.*\)
, und drucken Sie es aus, wenn dies der Fall ist.
who | awk '$5 ~ /\(.*\)/{print $5}'
Wenn Sie nur an ip
Adressen interessiert sind, ändern Sie den regulären Ausdruck:
who | awk '$5 ~ /\((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\)/{print $5}'
Antwort4
Wenn Sie nur die letzte Spalte erhalten möchten, wenn diese Spalte verfügbar ist, nutzen Sie die Tatsache, dass Zeilen, die Sienichtmöchte nur vier Spalten haben:
who | awk 'NF > 4 { print $NF }'
oder, um ähnliche Daten zu erhalten,
w -hi | awk '{ print $3 }'