Ersetzen Sie Zeilen nach einer bestimmten Anzahl von Übereinstimmungen in separaten Zeilen mit AWK

Ersetzen Sie Zeilen nach einer bestimmten Anzahl von Übereinstimmungen in separaten Zeilen mit AWK

Derzeit verwende ich AWK, um einen Teil einer Zeichenfolge nach den ersten drei Vorkommen eines Musters zu suchen und zu ersetzen. Die Zeichenfolge ist wie folgt formatiert: func(tempID="39849235",count='12');und es gibt viele dieser Zeichenfolgen in der Datei, wie unten gezeigt:

func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');

Verwenden vondieser Linkkonnte ich eine Methode finden, mit der ich mit AWK die ersten drei Instanzen der Zeichenfolge suchen und ersetzen kann. Ich habe es so geändert, wie ich es brauchte, und unten sehen Sie einen Ausschnitt meines Skripts:

id=12349876
awk -v id="$id" 'BEGIN {matches=0}
     matches < 3 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id"\""); matches++ }
     { print $0 }' filName.py >filName.py.changed

Das Ziel des obigen Codes ist es, jede Zeile mit tempID zu finden und die tempID zugewiesene Nummer durch einen Wert zu ersetzen, der in einer Variablen namens gespeichert ist $id. Das Suchen und Ersetzen funktioniert gut, aber jetzt möchte ich die Instanzen 4-9 durch eine andere Nummer ersetzen. Ich habe die folgende Methode ausprobiert, aber sie hat trotzdem nur die ersten 5 Instanzen von tempID ersetzt:

id2=39843237
awk -v id2="$id2" 'BEGIN {matches=4}
     matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\""); matches++ }
     { print $0 }' filName.py >filName.py.changed

Gibt es eine andere Möglichkeit, dies so umzusetzen, dass dieser Wertebereich ersetzt wird? Das muss nicht mit AWK sein, es kann mit sed oder einem anderen Linux-Dienstprogramm geschehen. Darüber hinaus muss die Lösung nicht unbedingt an einem bestimmten Punkt enden und darf alle Instanzen nach der dritten Zeile ersetzen, aber wenn es eine Lösung gibt, die dies kann, wäre das ein Plus.

Antwort1

Ihr matches=4und matches < 9meint „angenommen, es gab bereits 4 Übereinstimmungen, handeln Sie, bis insgesamt 9 vorhanden sind“. Deshalb werden die ersten 5 Instanzen ersetzt. Sie müssen wie zuvor bei 0 beginnen und dann die Untergrenze in die Logik einbeziehen:

id2=39843237
awk -v id2="$id2" 'BEGIN {matches=0}
 matches >=3 && matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\"") }
 /.*tempID.*/ { matches++ }
 { print $0 }' filName.py >filName.py.changed

Beachten Sie, dass Sie den Ersatz gemäß dem Wert von vornehmen müssen, matchesdiesen Wert jedoch jedes Mal erhöhen müssen, wenn eine Übereinstimmung auftritt. Ihr ursprünglicher Code ersetzte Text und erhöhte den Wert in einem Block. Als es keinen Ersatz gab, weil der Wert zu hoch war, wurde der Wert nicht weiter erhöht, aber das spielte keine Rolle mehr. Jetzt kommen Sie mit diesem einfachen Ansatz nicht mehr davon. Wenn es keinen Ersatz gibt, weil der Wert zu hoch war matches, wurde der Wert nicht weiter erhöht, aber das spielte keine Rolle mehr.matcheszu niedrigmüssen Sie den Wert dennoch erhöhen, wenn eine passende Zeichenfolge gefunden wird.

Daher die beiden {}Blöcke mit unterschiedlichen Bedingungen.

verwandte Informationen