meine textdatei sieht so aus:
Liquid penetration 95% mass (m) = 0.000205348
Liquid penetration 95% mass (m) = 0.000265725
Liquid penetration 95% mass (m) = 0.000322823
Liquid penetration 95% mass (m) = 0.000376445
Liquid penetration 95% mass (m) = 0.000425341
Jetzt möchte ich Liquid penetration 95% mass (m)
aus meinen Zeilen löschen , um nur die Werte zu erhalten. Wie soll ich das machen
grep -o '[^[:space:]]\+$' file
\S+$
entweder mit-E
oder akzeptiert-P
.) Diese Art von Lösung ist also nicht von Natur aus langsam. Aber ich komme immer noch nicht an diecut
Methode von αғsнιη heran , die auch Ihren Benchmark gewonnen hat .Antworten:
Wenn es nur ein
=
Zeichen gibt, können Sie alles vorher und einschließlich=
so löschen :Wenn Sie die Originaldatei ändern möchten, verwenden Sie die
-i
Option nach dem Testen:Anmerkungen
-r
benutze ERE, damit wir nicht entkommen müssen(
und)
s/old/new
ersetzenold
mitnew
.*
Beliebig viele beliebige Zeichen(things)
sparenthings
später mit Rückreferenzierung\1
,\2
usw.quelle
s/^.*= //
würde genauso gut funktionieren, da der richtige Wert am Ende der Zeile steht.\1
usw. verwendet, einen gewissen Wert für Leute, die landen auf dieser Frage bei der Suche, die nicht so ein einfaches Problem habenDies ist ein Job für
awk
; Angenommen, die Werte kommen nur im letzten Feld vor (gemäß Ihrem Beispiel):NF
ist eineawk
Variable, die auf die Anzahl der Felder in einem Datensatz (Zeile) erweitert wird und daher$NF
(beachten Sie, dass$
vorne) den Wert des letzten Felds enthält.Beispiel:
quelle
Ich habe mich entschlossen, die verschiedenen hier aufgeführten Lösungen zu vergleichen. Zu diesem Zweck habe ich eine große Datei erstellt, die auf dem vom OP bereitgestellten Inhalt basiert:
Ich habe eine einfache Datei mit dem Namen erstellt
input.file
:Dann habe ich diese Schleife ausgeführt:
Terminalfenster wurde blockiert. Ich habe
killall tee
von einem anderen Terminal ausgeführt. Dann überprüfte ich den Inhalt der Datei mit den Befehlen:less input.file
undcat input.file
. Es sah gut aus, bis auf die letzte Zeile. Also habe ich die letzte Zeile entfernt und eine Sicherungskopie erstellt:cp input.file{,.copy}
(aufgrund der Befehle, die die Option inplace verwenden ).Die endgültige Anzahl der Zeilen in der Datei
input.file
beträgt 2 192 473 . Ich habe diese Nummer durch den Befehl erhaltenwc
:Hier ist das Ergebnis des Vergleichs:
grep -o '[^[:space:]]\+$'
sed -ri 's/.* = (.*)/\1/'
Alternativ ist der Befehl schneller, wenn wir die Ausgabe in eine neue Datei umleiten:
gawk '{gsub(".*= ", "");print}'
rev | cut -d' ' -f1 | rev
grep -oP '.*= \K.*'
sed 's/.*= //'
(bzw. die-i
Option macht den Befehl einige Male langsamer)perl -pe 's/.*= //'
(Die-i
Option erzeugt hier keinen großen Unterschied in der Produktivität.)awk '{print $NF}'
cut -c 35-
cut -d= -f2
Die Quelle der Idee.
quelle
cut -d= -f2
Lösung . hahawc -l
werden außerdem drei Zahlen ausgegeben? Wenn keine anderen Optionen übergeben werden, sollte die-l
Option alles außer der Zeilenanzahl unterdrücken.wc
diese Leerzeichen tatsächlich angezeigt? Gibt es Gebietsschemaeinstellungen, für die dies möglich ist?) Vielen Dank für das Update!wc
einmal gelesen . Ich weiß nicht, wo mein Verstand heute früh war, aber ich konnte sie wirklich nicht verstehen. In der Tat waren die Leerzeichen Zifferngruppentrennzeichen undwc
fügen sie nicht hinzu :)Mit
grep
und der-P
für die mitPCRE
(Interpretieren des Musters als P erl- C ompatibel R egular E xpression) und die-o
allein abgestimmt Muster zu drucken. Die\K
Benachrichtigung ignoriert den übereinstimmenden Teil, der vor sich geht.Oder Sie könnten
cut
stattdessen den Befehl verwenden.quelle
cut
Verfahren in dieser Antwort war auch der klare Sieger in einem kleineren Maßstab Ich lief die getestet weniger Methoden , sondern verwenden eine größere Eingabedatei. Es war weit über zehnmal schneller als die schnelle Variante der Methode, die ich persönlich mag (und bei der es hauptsächlich um meine Antwort geht).Da das Zeilenpräfix immer dieselbe Länge hat (34 Zeichen), können Sie Folgendes verwenden
cut
:quelle
Kehren Sie den Inhalt der Datei mit um
rev
, leiten Sie die Ausgabecut
mit Leerzeichen als Trennzeichen und 1 als Zielfeld weiter und kehren Sie sie dann erneut um, um die ursprüngliche Nummer zu erhalten:quelle
Dies ist einfach, kurz und leicht zu schreiben, zu verstehen und zu überprüfen, und ich persönlich mag es:
grep
Wenn in Ubuntu mit-E
oder aufgerufen wird-P
, bedeutet die Kurzschreibweise\s
ein Leerzeichen (in der Praxis normalerweise ein Leerzeichen oder ein Tabulator) und\S
etwas anderes. Mit dem Quantor+
und den End-of-Line - Anker$
, das Muster für\S+$
ein oder mehr Nicht-Leerzeichen am Ende einer Zeile . Sie können-P
anstelle von verwenden-E
; Die Bedeutung ist in diesem Fall gleich, es wird jedoch eine andere reguläre Ausdrucks-Engine verwendet, sodass sie möglicherweise unterschiedliche Leistungsmerkmale aufweisen .Dies entspricht der kommentierten Lösung von Avinash Raj (nur mit einer einfacheren, kompakteren Syntax):
Diese Ansätze funktionieren nicht, wenn hinter der Zahl ein Leerzeichen stehen könnte . Sie können geändert werden, aber ich sehe keinen Grund, hier darauf einzugehen. Obwohl es manchmal lehrreich ist, eine Lösung zu verallgemeinern, um in mehreren Fällen zu arbeiten, ist es nicht praktisch, dies fast so oft zu tun, wie die Leute annehmen, weil man normalerweise nicht weiß, auf welche von vielen verschiedenen inkompatiblen Arten das Problem letztendlich benötigt wird verallgemeinert werden.
Leistung ist manchmal ein wichtiger Gesichtspunkt. Diese Frage besagt nicht, dass die Eingabe sehr umfangreich ist, und es ist wahrscheinlich, dass jede hier veröffentlichte Methode schnell genug ist. Für den Fall, dass Geschwindigkeit gewünscht wird, finden Sie hier einen kleinen Benchmark für eine 10-Millionen-Zeilen-Eingabedatei:
Ich habe es zweimal ausgeführt, für den Fall, dass die Reihenfolge wichtig ist (wie es manchmal für E / A-schwere Aufgaben der Fall ist), und weil ich keine Maschine zur Verfügung hatte, die keine anderen Aufgaben im Hintergrund ausführte, die die Ergebnisse verzerren könnten. Aus diesen Ergebnissen schließe ich zumindest vorläufig und für Eingabedateien der von mir verwendeten Größe Folgendes:
Beeindruckend! Passing
-P
(zu Verwendung PCRE ) statt-G
(die Standardeinstellung , wenn kein Dialekt angegeben wird) oder-E
ausgrep
schneller um mehr als eine Größenordnung. Für große Dateien ist es möglicherweise besser, diesen Befehl zu verwenden als den oben gezeigten:BEEINDRUCKEND!! Das
cut
Verfahren in αғsнιη Antwort , ist über eine Größenordnung schneller als auch die schnellere Version meiner Art und Weise! Es war auch der Gewinner im Benchmark von pa4080 , der mehr Methoden als diese, aber mit geringerem Input abdeckte - und aus diesem Grund habe ich es von allen anderen Methoden ausgewählt, um es in meinen Test aufzunehmen. Wenn Leistung wichtig ist oder Dateien sehr groß sind, sollte meiner Meinung nach die Methode von αιsнιη verwendet werden.cut -d= -f2 file
cut
Dies dient auch als Erinnerung daran, dass die einfachen
cut
undpaste
Hilfsprogramme nicht vergessen werden sollten und gegebenenfalls bevorzugt werden sollten, obwohl es komplexere Tools wiegrep
diese gibt, die häufig als First-Line-Lösungen angeboten werden (und an die ich persönlich gewöhnter bin) verwenden).quelle
perl
- s ubstitute das Muster/.*= /
mit leeren String//
:Von
perl --help
:sed
- Ersetze das Muster durch eine leere Zeichenkette:oder (aber langsamer als oben) :
gawk
- Ersetzen Sie das Muster".*= "
durch eine leere Zeichenkette""
:Von
man gawk
:quelle