Löschen Sie Zeilen aus einer Datei mit awk oder sed basierend auf der Variablen aus dem vorherigen Befehl

Löschen Sie Zeilen aus einer Datei mit awk oder sed basierend auf der Variablen aus dem vorherigen Befehl

Ich habe eine CSV-Datei (sagen wir temp.csv) mit Zeichenfolgen und Zahlen. Ich muss die Zeilen löschen, die am Zeilenanfang in der Datei ein bestimmtes Zeichenfolgenmuster enthalten. Hier ist beispielsweise meine Datei -

req1,incl_patt1,excl_patt1,2,ind1
req1,incl_patt2,excl_patt2,1,ind1
req1,incl_patt3,excl_patt3,4,ind1
req2,inc_patt1,exc_patt1,1,ind2
req2,inc_patt2,exc_patt2,2,ind2
req2,inc_patt3,exc_patt3,3,ind2
req3,pattern3,expatt3,1,ind3
req4,pattern4,expatt4,1,ind4

Ich schreibe ein Muster req_file_currin einen Befehl ~ $ req_file_curr=req1

echo "${req_file_curr}"gibt die Ausgabe alsreq1

Bei der Verwendung in einemsedBefehl, wie unten:

sed '/\"${req_file_curr}\"/d' temp.csv

gibt die Ausgabe als

req1,incl_patt1,excl_patt1,2,ind1
req1,incl_patt2,excl_patt2,1,ind1
req1,incl_patt3,excl_patt3,4,ind1
req2,inc_patt1,exc_patt1,1,ind2
req2,inc_patt2,exc_patt2,2,ind2
req2,inc_patt3,exc_patt3,3,ind2
req3,pattern3,expatt3,1,ind3
req4,pattern4,expatt4,1,ind4

Ich erwarte die Ausgabe als

req2,inc_patt1,exc_patt1,1,ind2
req2,inc_patt2,exc_patt2,2,ind2
req2,inc_patt3,exc_patt3,3,ind2
req3,pattern3,expatt3,1,ind3
req4,pattern4,expatt4,1,ind4

Wie kann ich die Variable aus einer Shell als Suchmuster verwenden insedoderawk?

Antwort1

Sie müssen das sedMuster in doppelte Anführungszeichen setzen, damit die Shell die Variable erweitern kann, bevor sie sie an Folgendes übergibt sed:

sed "/^${req_file}/d" temp.csv

Sie müssen den Anker auch verwenden, ^um anzuzeigen sed, dass dieses Muster am Anfang der Zeile stehen muss.

Antwort2

Kein Bedarf für awkoder sedhier:

grep -v "^$req_file_curr," file

Beachten Sie, dass (wie bei „for“ sedoder awk„, allerdings in geringerem Maße“) davon ausgegangen wird, dass $req_file_currkeine Regexp-Operatoren (wie „ ., *…“) enthalten sind.

Wenn dies der Fall ist, müssen Sie diese Zeichen maskieren. Alternativ awkkönnen Sie einen Ansatz verwenden, der die index()Funktion verwendet:

S="$req_file_curr," awk 'index($0, ENVIRON["S"]) != 1' < file

Antwort3

Sie haben festgelegt req_file_curr, aber verwenden req_file. Und Ihr sedBefehl funktioniert nicht, da die Shell-Variable in Ihrem sedBefehl nicht erweitert werden kann.

Sie können Folgendes versuchen:

$ sed '/'"${req_file_curr}"'/d' file
req2,inc_patt1,exc_patt1,1,ind2
req2,inc_patt2,exc_patt2,2,ind2
req2,inc_patt3,exc_patt3,3,ind2
req3,pattern3,expatt3,1,ind3
req4,pattern4,expatt4,1,ind4

oder sedmit Anführungszeichen:

sed "/${req_file_curr}/d" file

und mit awk:

$ awk -v req=$req_file_curr '$0 !~ req' file
req2,inc_patt1,exc_patt1,1,ind2
req2,inc_patt2,exc_patt2,2,ind2
req2,inc_patt3,exc_patt3,3,ind2
req3,pattern3,expatt3,1,ind3
req4,pattern4,expatt4,1,ind4

Antwort4

Eine Lösung für erektile Dysfunktion wäre etwa so:

  req_file_curr=req1

  printf '%s\n' "g/^$req_file_curr/d"  w | ed -s temp.csv

Die Datei wird direkt bearbeitet. Testen Sie dies also zuerst, bevor Sie es für Ihre Dateien ausführen.

verwandte Informationen