Wie verwende ich cut, um mehrere Leerzeichen voneinander zu trennen?

22

Ich möchte die letzte Spalte dieses Beispiels erhalten:

[  3]  1.0- 2.0 sec  1.00 MBytes  8.39 Mbits/sec
[  3]  2.0- 3.0 sec   768 KBytes  6.29 Mbits/sec
[  3]  3.0- 4.0 sec   512 KBytes  4.19 Mbits/sec
[  3]  4.0- 5.0 sec   256 KBytes  2.10 Mbits/sec
...

Wenn ich benutze

cut -d\  -f 13

Ich bekomme

Mbits/sec
6.29
4.19
2.10

weil manchmal zusätzliche Leerzeichen dazwischen sind.

rubo77
quelle
Die letzte Spalte ist Mbits/sec, ist es das, was Sie wollen oder die 2 letzten Spalten?
Terdon
1
Ich möchte nur die
zweitletzte

Antworten:

16

Um Ihre Frage wörtlich zu beantworten:

sed 's/   */:/g' | cut -d : -f 5

oder

awk -F '  +' '{print $5}'

Das geht aber nicht, wenn die Zahl in Klammern 10 usw. erreicht. Wenn Sie nur an den Zahlen interessiert sind, können Sie alles andere entfernen.

sed 's/[^.0-9][^.0-9]*/:/g' | cut -d : -f 6
Gilles 'SO - hör auf böse zu sein'
quelle
Ja, sicher, nur die Zahlen, aber nur Ihr
drittes
@ rubo77 Funktioniert bei mir. Die ersten beiden Beispiele machen genau das, wonach Sie in Ihrem Titel fragen. Oder wollten Sie das Gerät auch abstreifen? Fügen Sie in diesem Fall | sed 's/ .*//'am Ende der ersten beiden Beispiele hinzu. Natürlich gibt es noch viele andere Möglichkeiten.
Gilles 'SO- hör auf böse zu sein'
etwas kürzer mit +statt *: Katzentest | sed 's / [^. 0-9] \ + /: / g' | cut -d: -f 6
rubo77
@ rubo77 Wenn dein sed es unterstützt, ist das. Es wird von GNU und BusyBox unterstützt, aber nicht von BSD oder Solaris. POSIX gibt +und ?in ERE an, lässt aber \+und \?in BRE undefiniert.
Gilles 'SO- hör auf, böse zu sein'
21

Wenn wir den trBefehl zusammen mit der Option squeeze ( -sFlag) verwenden, um alle mehreren aufeinander folgenden Leerzeichen in ein einzelnes Leerzeichen zu konvertieren und dann die cutOperation mit Leerzeichen als Begrenzer auszuführen, können wir auf die erforderliche Spalte mit den Zahlen zugreifen.

Beziehen Sie sich auf den unten abgebildeten Code:

cat file | tr -s ' ' | cut -d ' ' -f 8

Wald Schilfrohr
quelle
4
Diese Antwort sollte höher sein; Es ist bei weitem die einfachste und am besten lesbare Lösung.
Luke Davis
5

Diese Befehle geben alle die letzte Spalte einer durch Leerzeichen getrennten Datei aus:

  • awk '{print $NF}' file

    in awk, NFist die Anzahl der Felder und $NFist das letzte Feld.

  • perl -lane 'print $F[$#F]' file

    -aTeilt die Datei auf Whitespace in das Array @F, $#Fist die Anzahl der Elemente im Array und $F[$#F]ist das letzte Element. Das -nMittel liest die in der Befehlszeile angegebene Datei und wendet das mit -ejeder Zeile übergebene Skript an . -lFügt einfach \njeder printAnweisung ein Zeilenumbruchzeichen ( ) hinzu .

  • sed 's/.* //g'

    Ein einfacher regulärer Ausdruck, der alles mit dem letzten Leerzeichen vergleicht und es löscht, wobei nur die letzte Spalte übrig bleibt.

  • rev file | cut -d' ' -f 1 | rev

    revKehrt die Ausgabe um, so dass das letzte Feld das erste ist, cutmit einem Begrenzungszeichen, um es zu drucken und revden Text auf den normalen Wert zurückzusetzen. Dies funktioniert nicht, wenn aufeinanderfolgende Leerzeichen verwendet werden .

Aufgrund Ihrer Eingaben möchten Sie wahrscheinlich nicht die letzte Spalte, sondern die vorletzte oder die beiden letzten. In diesem Fall verwenden Sie diese, um die letzten 2 ( 8.39 Mbits/sec) zu drucken :

awk '{print $(NF-1),$NF}' file 
perl -lane 'print "$F[$#F-1] $F[$#F]"' file 
sed 's/.* \(.* .*\)/\1/' file 
rev file | cut -d' ' -f 1,2 | rev

und diese, um das vorletzte ( 8.39) zu drucken :

awk '{print $(NF-1)}' file 
perl -lane 'print $F[$#F-1]' file 
sed 's/.* \(.*\) .*/\1/' file 
rev file | cut -d' ' -f 2 | rev
terdon
quelle
4

Sie können das mehrfache Auftreten von Leerzeichen nicht anhand der folgenden Anweisungen trennen cut:

Ausgabefelder werden durch ein einzelnes Vorkommen des Feldtrennzeichens getrennt.

es sei denn, der Text ist um den gleichen Betrag voneinander getrennt oder Sie trentfernen überschüssigen Text .

Verwenden Sie ansonsten alternative Tools wie awk, sedoder ex.

Beispielsweise:

ex -s +'%norm $2Bd0' +%p +q! foo.txt

Ersetzen Sie +q!durch -cwq, um die Änderungen zu speichern.

Kenorb
quelle
0

Verwenden Sie einen Perl-Einzeiler wie folgt:

perl -lane 'print $F[-2]' input_file

Erläuterung:

Option -everanlasst den Perl-Interpreter, nach dem Skript inline und nicht in einer Datei zu suchen.

Die Option -nbewirkt, dass die Eingabe (Datei oder STDIN aus einer Pipe) zeilenweise gelesen wird.

Die Option entfernt -ldas Trennzeichen für Eingabedatensätze (standardmäßig betriebssystemabhängig, Zeilenumbruch unter UNIX) nach dem Lesen der Zeile und fügt es am Ende zu jeder Zeile hinzuprint

Option -abewirkt , dass jede Eingangsleitung aufgeteilt wird auf Leerzeichen in einem Array @F, und $F[-2]ist das zweite Element des Zählen von dem Ende, das ist das Feld gewünscht wird . Sie können auch verwenden $F[$#F-1], wo $#Fder letzte Index des Arrays ist @F, der etwas weniger lesbar ist.

Timur Shtatland
quelle