Versuchen Sie dies (Gawk wird benötigt).
awk '{a=gensub(/.*#([0-9]+)(\").*/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+\"/,a+11"\"",$0);}print $0}' YourFile
Testen Sie mit Ihrem Beispiel:
kent$ echo '(bookmarks
("Chapter 1 Introduction 1" "#1"
("1.1 Problem Statement and Basic Definitions 2" "#2")
("Exercises 30" "#30")
("Notes and References 34" "#34"))
)
'|awk '{a=gensub(/.*#([0-9]+)(\").*/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+\"/,a+11"\"",$0);}print $0}'
(bookmarks
("Chapter 1 Introduction 12" "#12"
("1.1 Problem Statement and Basic Definitions 13" "#13")
("Exercises 41" "#41")
("Notes and References 45" "#45"))
)
Beachten Sie, dass dieser Befehl nicht funktioniert, wenn sich die beiden Zahlen (z. B. 1 "und" # 1 ") unterscheiden oder wenn sich mehrere Zahlen in derselben Zeile mit diesem Muster befinden (z. B. 23" ... 32 "..." # 123 ") in einer Zeile.
AKTUALISIEREN
Da @Tim (OP) angibt, dass die Zahl, die "
in derselben Zeile steht, unterschiedlich sein kann, habe ich einige Änderungen an meiner vorherigen Lösung vorgenommen und sie für Ihr neues Beispiel funktionsfähig gemacht.
Übrigens, aufgrund des Beispiels habe ich das Gefühl, dass es sich um ein Inhaltsverzeichnis handeln könnte, sodass ich nicht sehe, wie sich die beiden Zahlen unterscheiden könnten. Das erste wäre die gedruckte Seitennummer und das zweite mit # wäre der Seitenindex. Habe ich recht?
Wie auch immer, Sie kennen Ihre Anforderungen am besten. Jetzt die neue Lösung, immer noch mit Gawk (ich teile den Befehl in Zeilen auf, um das Lesen zu erleichtern):
awk 'BEGIN{FS=OFS="\" \"#"}{if(NF<2){print;next;}
a=gensub(/.* ([0-9]+)$/,"\\1","g",$1);
b=gensub(/([0-9]+)\"/,"\\1","g",$2);
gsub(/[0-9]+$/,a+11,$1);
gsub(/^[0-9]+/,b+11,$2);
print $1,$2
}' yourFile
teste mit deinem neuen Beispiel:
kent$ echo '(bookmarks
("Chapter 1 Introduction 1" "#1"
("1.1 Problem Statement and Basic Definitions 23" "#2")
("Exercises 31" "#30")
("Notes and References 42" "#34"))
)
'|awk 'BEGIN{FS=OFS="\" \"#"}{if(NF<2){print;next;}
a=gensub(/.* ([0-9]+)$/,"\\1","g",$1);
b=gensub(/([0-9]+)\"/,"\\1","g",$2);
gsub(/[0-9]+$/,a+11,$1);
gsub(/^[0-9]+/,b+11,$2);
print $1,$2
}'
(bookmarks
("Chapter 1 Introduction 12" "#12"
("1.1 Problem Statement and Basic Definitions 34" "#13")
("Exercises 42" "#41")
("Notes and References 53" "#45"))
)
EDIT2 basierend auf @Tims Kommentar
(1) Bedeutet FS = OFS = "\" \ "#", dass das Feldtrennzeichen in Eingabe und Ausgabe doppelte Anführungszeichen, Leerzeichen, doppelte Anführungszeichen und # ist? Warum doppeltes Anführungszeichen zweimal angeben?
Sie sind sowohl im Eingabe- als auch im Ausgabeteil für das Trennzeichen richtig. Es definierte Trennzeichen als:
" "#
Es gibt zwei doppelte Anführungszeichen, da es einfacher ist, die beiden gewünschten Zahlen zu erfassen (basierend auf Ihrer Beispieleingabe).
(2) Bedeutet $ in /.* ([0-9] +) $ / das Ende der Zeichenfolge?
Genau!
(3) Was ist der Unterschied zwischen "g" und "G" im dritten Argument von gensub ()? Es gibt keinen Unterschied zwischen G und g. Überprüfen Sie dies heraus:
gensub(regexp, replacement, how [, target]) #
Search the target string target for matches of the regular expression regexp.
If "how" is a string beginning with ‘g’ or ‘G’ (short for “global”), then
replace all matches of regexp with replacement.
Dies ist von http://www.gnu.org/s/gawk/manual/html_node/String-Functions.html . Sie können lesen, um eine detaillierte Verwendung von gensub zu erhalten.