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=4
und matches < 9
meint „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, matches
diesen 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.matches
zu niedrigmüssen Sie den Wert dennoch erhöhen, wenn eine passende Zeichenfolge gefunden wird.
Daher die beiden {}
Blöcke mit unterschiedlichen Bedingungen.