Shell-Skript: Möchten Sie zwei aufeinanderfolgende Zeilen löschen, die dem Muster einer bestimmten Zeile entsprechen

Shell-Skript: Möchten Sie zwei aufeinanderfolgende Zeilen löschen, die dem Muster einer bestimmten Zeile entsprechen

Ich möchte zwei bestimmte aufeinanderfolgende Zeilen löschen, die mit Mustern aus einer bestimmten Zeile einer Datei übereinstimmen.

Der Dateiinhalt sieht beispielsweise wie folgt aus:

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc

Ich möchte die Zeilen ab Zeile 4 suchen, die dem Muster der ersten Zeile entsprechen, das mit „Name:“ beginnt, und die dem Muster der zweiten Zeile entsprechen, das mit einem Leerzeichen beginnt, und die beiden aufeinanderfolgenden Zeilen löschen.

sedGibt es eine effiziente Möglichkeit, dies mithilfe der Shell oder auf andere Weise zu tun ?

Um es etwas deutlicher zu machen: Ich möchte Signatur-/Prüfsummeninformationen aus MANIFEST.MF entfernen.

Beispiel für MANIFEST.MF wie unten: Aus der unten stehenden Manifestdatei möchte ich den Eintrag „Name: “ entfernen. Dabei kann der Eintrag „Name: “ eine oder zwei (oder mehr) Zeilen umfassen.

Meine Lösung bestand zunächst darin, den ersten Eintrag „Name:“ zu suchen, gefolgt vom Eintrag „SHA-256-Digest:“, und dann bis zum Ende der Datei zu löschen. Leider besteht bei dieser Lösung das Problem, dass ein benötigter Eintrag in der Mitte entfernt wird. Beispielsweise wird „NetBeans-Simply-Convertible:“ ebenfalls entfernt.

Ich möchte jetzt den Eintrag „Name:“ entfernen, wenn er in einer Zeile vorhanden ist oder sich über zwei oder mehr Zeilen erstreckt. Beim Entfernen von „Name:“-Einträgen sollten jedoch keine Einträge wie „NetBeans-Simply-Convertible:“ verloren gehen.

Ich entferne bereits "SHA-256-Digest: "-Einträge mit dem folgenden Befehl aus der Datei mitsed -i "/^\SHA-256-Digest: /d" $manifest_file


Manifest-Version: 1.0
Version-Info: ....

Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
 onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=

Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
 $5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=

Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=

Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...

Erwartete Ausgabe:

Manifest-Version: 1.0
Version-Info: ....


NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties

...

Antwort1

awkAnsatz:

Nehmen wir an, wir haben die folgende Eingabedatei file.txt(wobei jede Zeile Line<number>:als erstes Feld enthält):

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc
Line12: Name: 333
Line13:  ccc

awk '{ if ($2 == "Name:") { 
           if ((getline l) > 0){ 
               if (l ~ /^\S+  \S+/) { next } else { print $0 RS l }               
           }
       } else { print } 
}' file.txt

Die Ausgabe:

Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc

'getline var'- liest den nächsten Datensatz aus der awk-Eingabe in die Variablevar

DergetlineDer Befehl gibt 1 zurück, wenn ein Datensatz gefunden wird, und 0, wenn das Dateiende erreicht ist.

Antwort2

Sie sehen, dass Ihre Frage nicht klar ist: Eine Antwort löscht 4 Zeilen (die beiden übereinstimmenden und die beiden nachfolgenden); eine andere löscht allesAberdie passenden Zeilen...

Ich werfe ein, was ich verstehe, was Sie wollen: Ich lösche 2 Zeilen, die übereinstimmende Name: 123und die folgende. Ich mache das mit sed:

sed -e '/Name: 123/{N;d}' filename

Antwort3

Verwendung von ed:

$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....

NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties

Dadurch wird das folgende Bearbeitungsskript auf Ihre Eingabedatei angewendet:

g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q

Dieses besteht aus sechs einzelnen Befehlen:

  1. Die beiden Befehle s///werden -,. jauf jede Zeile angewendet, die mit einem Leerzeichen beginnt. Der leere reguläre Ausdruck im sBefehl verwendet den Ausdruck ^des vorhergehenden gBefehls erneut (der zum Anwenden eines oder mehrerer Befehle auf Zeilen verwendet wird, die einem regulären Ausdruck entsprechen), sodass der sBefehl das erste Leerzeichen in Zeilen entfernt, die mit Leerzeichen beginnen. Der jBefehl verbindet dann die geänderte Zeile mit der vorherigen Zeile. Dadurch wird der Zeilenumbruch in den Eingabedaten effektiv rückgängig gemacht.

  2. Der Befehl dwird auf alle Zeilen angewendet, die mit beginnen Name:, und entfernt diese.

  3. Ebenso SHA-256-Digest:werden Zeilen entfernt, die mit beginnen.

  4. Ab Zeile 4 werden leere Zeilen entfernt.

  5. Um das Ergebnis anzuzeigen, geben wir den kompletten Puffer auf die Standardausgabe aus.

  6. Qbeendet den Editor bedingungslos (Sie könnten verwenden, wqum die Änderungen in die Originaldatei zurückzuschreiben).

Antwort4

sed -e '
   4,$!d;      # skip non-relevant portion
   /Name:/N;   # grab the line coming after Name:
   /\n.* /d;   # what we were after is not this
   P;D
' yourfile

verwandte Informationen