Extrahieren eines Teils von Linien mit einem bestimmten Muster mit awk, sed


18

Ich habe eine Frage zu den awk / sed-Operatoren. Ich habe eine große Datei, die folgende Reihe von Zeilen wiederholt hat

Expression loweWallrhoPhi :  sum=-6.97168e-09
Expression leftWallrhoPhi :  sum=6.97168e-09
Expression lowerWallPhi :  sum=-5.12623e-12
Expression leftWallPhi :  sum=5.12623e-12
Expression loweWallrhoUSf :  sum=-6.936e-09
Expression leftWallrhoUSf :  sum=6.97169e-09
Expression lowerWallUSf :  sum=-5.1e-12
Expression leftWallUSf :  sum=5.12624e-12

Ich möchte Wert nach Summe jeweils in separate Datei extrahieren. Ist es möglich, dies auf einmal zu tun?

Antworten:


26

Mit grep Befehl:

grep -oP 'sum=\K.*' inpufile > outputfile

grep with -P(perl-regexp) unterstützt Parameter \K, mit denen die zuvor übereinstimmenden Zeichen ignoriert werden.

Mit awk Befehl:

awk -F"=" '{print $NF}' inputfile > outputfile

Awk NFgibt Ihnen die Gesamtzahl der Felder in einem Datensatz / einer Zeile an. Der letzte Wert davon ist also die letzte Feldnummer in einem Datensatz / einer Zeile.

Mit sed Befehl:

sed 's/^.*sum=//' inpufile > outputfile

^.*=sumErsetzen Sie alle Zeichen ( .*) zwischen dem Zeilenanfang ( ^) und den letzten Zeichen ( sum=) durch Leerzeichen.

Ergebnis:

-6.97168e-09
6.97168e-09
-5.12623e-12
5.12623e-12
-6.936e-09
6.97169e-09
-5.1e-12
5.12624e-12

Wenn Sie jeden Wert in einer separaten Datei speichern möchten, verwenden Sie die obigen Befehle in einer while-Schleife:

while read line; do
    echo "$line" | grep -oP 'sum=\K.*'     > $(echo "$line" |awk '{print $2}');
   #echo "$line" | awk -F"=" '{print $NF}' > $(echo "$line" |awk '{print $2}');
   #echo "#line" | sed 's/^.*sum=//'       > $(echo "$line" |awk '{print $2}');
done < file

Das schließt das ein sum=und das ist nicht derselbe wie der Wert nachsum=
Anthon

OP will den Wert nach Summe, auch die awk-Beschreibung von NF ist schrecklich.

1
Zum Abschluss dieses sehr gute Antwort, können Sie auch cut: cut -d'=' -f2 file.
Fedorqui

Das ist eine sehr gute Antwort. Ich mochte es. Vielen Dank.
Jaffer Wilson

6

Wenn ich die Frage richtig verstehe, möchten Sie erst Werte abrufen =und diese Werte in separaten Dateien basierend auf dem zweiten Feld (?) Speichern. Wenn ich recht habe, versuche es so:

$ awk -F'[ =]' '{print $6>"file_"$2".txt"}' file

Das Ergebnis:

$ ls -1
  file_leftWallPhi.txt
  file_leftWallUSf.txt
  file_leftWallrhoPhi.txt
  file_leftWallrhoUSf.txt
  file_loweWallrhoPhi.txt
  file_loweWallrhoUSf.txt
  file_lowerWallPhi.txt
  file_lowerWallUSf.txt

$ cat  file_leftWallPhi.txt
  5.12623e-12

@KasiyA Ich kann Ihr Problem mit GNU awk 4.0.2 nicht reproduzieren. Der Befehl aus meiner Antwort funktioniert auch mit der -cOption (Kompatibilitätsmodus mit herkömmlichem UNIX, awkbei dem GNU-Erweiterungen deaktiviert sind). Stellen Sie sicher, dass Sie die Eingabedatei aktualisiert haben, da die ursprüngliche Frage bearbeitet und leere Zeilen gelöscht wurden.
Jimmy

1

Sie können es tun, indem Sie sed

sed -E 's/^.* (\S+)\s*:.*=(\S+)/echo "\2" > "\1".txt/' file | bash

Das Skript findet zwei Teile in einer Reihe heraus:

  1. zwischen Leerzeichen und :und sollten einige (mehr als 0) Nicht-Leerzeichen enthalten;
  2. einige (mehr als 0) Nicht-Leerzeichen danach =;

und formatiere von seinem in-Execution-Befehl, der über die Pipe an übertragen wurde bash


Eine viel vielseitigere Antwort.
Duanev
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.