Prova questo (è necessario gawk).
awk '{a=gensub(/.*#([0-9]+)(\").*/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+\"/,a+11"\"",$0);}print $0}' YourFile
Prova con il tuo esempio:
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"))
)
Si noti che questo comando non funzionerà se i due numeri (ad es. 1 "e" # 1 ") sono diversi. Oppure se ci sono più numeri nella stessa riga con questo modello (ad es. 23" ... 32 "..." # 123 ") in una riga.
AGGIORNARE
Poiché @Tim (OP) ha detto che il numero seguito dalla "
stessa riga potrebbe essere diverso, ho apportato alcune modifiche alla mia soluzione precedente e l'ho fatto funzionare per il tuo nuovo esempio.
A proposito, dall'esempio sento che potrebbe essere una tabella della struttura dei contenuti, quindi non vedo come i due numeri potrebbero essere diversi. Il primo sarebbe il numero di pagina stampato e il secondo con # sarebbe l'indice di pagina. Ho ragione?
Ad ogni modo, conosci meglio le tue esigenze. Ora la nuova soluzione, sempre con gawk (spezzo il comando in righe per facilitarne la lettura):
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
prova con il tuo nuovo esempio:
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 basato sul commento di @Tim
(1) FS = OFS = "\" \ "#" significa che il separatore di campo sia in input che in output è virgoletta doppia, spazio, virgoletta doppia e #? Perché specificare due virgolette due volte?
Hai ragione per il separatore sia nella parte di input che in quella di output. Ha definito il separatore come:
" "#
Esistono due virgolette doppie, perché è più facile catturare i due numeri desiderati (in base all'input di esempio).
(2) In /.* ([0-9] +) $ /, $ indica la fine della stringa?
Esattamente!
(3) Nel terzo argomento di gensub (), qual è la differenza tra "g" e "G"? non c'è differenza tra G e g. Controllalo:
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.
Questo è da http://www.gnu.org/s/gawk/manual/html_node/String-Functions.html . puoi leggere per ottenere un uso dettagliato di gensub.