
Ich möchte einen Wert innerhalb eines Awk-Blocks suchen und ersetzen.
Hier ist eine Beispiel-Eingabedatei für mein Skript
P1
10,9:11/18013013582
,10:1
,167:0
,487:5/E.164
11,9:15/310410532169026
,10:60
,167:0
,487:4/IMSI
12,18:15/013329002130500
,19:0
15,9:10/9609610015
,10:1
,14:68
,167:0
,436:5/ABCDE
,487:5/E.164
16,87:1
17,9:10/8013765024
,10:1
,11:1
,12:0
,167:0
,487:5/E.164
23,9:11/13123149810
,10:1
,11:1
,167:0
,487:5/E.164
P3
42,3:1.
,4:3
,300:1.
43,3:1.
,4:3
,300:1.
44,3:0.
,4:7
,300:0.
45,5:0.3
Und hier ist der Codeabschnitt, den ich derzeit verwende:
nawk -v fname="${filename}" -F '/|:' '
function isnum(x){return(x==x+0)}
/P1/,/P3/{
# Found start increment i reset variables go to next line
if(/P1/){
++i
fid =""
count++
next
}
# Found end validate variable and print go to next line
if(/P3/){
printf "%s|",count
printf "%s|",isnum(fid)?fid:"NULL"
next
}
if(!fid && /36,59:*/)
{
fid = $NF
}
' ${filename} >>output.txt
Meine Eingabedatei enthält im Wesentlichen mehrere P1/P3-Blöcke. Ich nehme einen Block nach dem anderen und finde den Wert daraus heraus. Was ich nun im Wesentlichen tun möchte, ist, den Wert von first ,11 zu ändern:1(also der nach Teil 17,9) in 11:2basierend auf dem Wert von 17,9:10/8013765024.
Bitte beachten Sie, dass davor und danach mehrere ,11 stehen können, diese müssen jedoch unverändert bleiben.
Bitte geben Sie mir Tipps, wie ich weiter vorgehen soll. Ich bin mit awk und sed völlig unerfahren.
Außerdem habe ich versucht, einen regulären Ausdruck zu schreiben, konnte ihn aber nicht richtig herausfinden. Hier ist er:
17[,0-9:\]*[\n]*,11
Antwort1
Probieren Sie diesen awk-Befehl aus. Immer wenn awk eine Zahl findet, die mit 80
Spalte 2 beginnt, holt es die nächste Zeile und dann die nächste Zeile und ändert deren Wert, um ,11:2
die anderen Zeilen unverändert auszudrucken.
$ awk -F/ '$2~/^80/{print; getline; print; getline; $1=",11.2"}1' file1.txt
P1
10,9:11/18013013582
,10:1
,167:0
,487:5/E.164
11,9:15/310410532169026
,10:60
,167:0
,487:4/IMSI
12,18:15/013329002130500
,19:0
15,9:10/9609610015
,10:1
,14:68
,167:0
,436:5/ABCDE
,487:5/E.164
16,87:1
17,9:10/8013765024
,10:1
,11.2
,12:0
,167:0
,487:5/E.164
23,9:11/13123149810
,10:1
,11:1
,167:0
,487:5/E.164
P3
42,3:1.
,4:3
,300:1.
43,3:1.
,4:3
,300:1.
44,3:0.
,4:7
,300:0.
45,5:0.3
Antwort2
Hier ist eine awk
Lösung:
$ awk -F '/|:' '
$3 == "8013765024" {flag = 1}
$0 == ",11:1" && flag {$2 = 2;flag = 0}
1
' OFS=':' file
Antwort3
Hier ist eine mögliche sed
Lösung:
sed '/17,9:10\/80/,/11:1/ {
s/8013765024/+118013765024/
s/11:1/11:2/ }' file.txt
Dies startet die Ersetzung, nachdem es gefunden 17,9:10/80
und zuerst angehängt wurde +11
, 8013765024
und +118013765024
ersetzt es auch nur 11:1
durch 11:2
das erste Vorkommen von 11:1
(der Bereich ist inklusiv).
Beim Ausführen diff
der Ausgabe von sed
und der ursprünglichen Datei wird Folgendes angezeigt:
19c19
< 17,9:10/+118013765024
---
> 17,9:10/8013765024
21c21
< ,11:2
---
> ,11:1
Das bedeutet, dass die einzigen Änderungen an der Datei das Hinzufügen von [ +11
] und das Ersetzen von [ 11:1
] durch [ 11:2
] sind. Lassen Sie mich wissen, ob das richtig ist.