Prueba esto (se necesita gawk).
awk '{a=gensub(/.*#([0-9]+)(\").*/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+\"/,a+11"\"",$0);}print $0}' YourFile
Prueba con tu ejemplo:
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"))
)
Tenga en cuenta que este comando no funcionará si los dos números (por ejemplo, 1 "y" # 1 ") son diferentes, o si hay más números en la misma línea con este patrón (por ejemplo, 23" ... 32 "..." # 123 ") en una línea.
ACTUALIZAR
Como @Tim (OP) dijo que el número seguido de la "
misma línea podría ser diferente, hice algunos cambios en mi solución anterior y lo hice funcionar para su nuevo ejemplo.
Por cierto, del ejemplo siento que podría ser una tabla de estructura de contenido, por lo que no veo cómo los dos números podrían ser diferentes. Primero sería el número de página impresa, y segundo con # sería el índice de la página. Estoy en lo cierto?
De todos modos, conoces mejor tus requisitos. Ahora la nueva solución, todavía con gawk (divido el comando en líneas para que sea más fácil de leer):
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
prueba con tu nuevo ejemplo:
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 basado en el comentario de @Tim
(1) ¿FS = OFS = "\" \ "#" significa que el separador de campo tanto en la entrada como en la salida es comillas dobles, espacios, comillas dobles y #? ¿Por qué especificar comillas dobles dos veces?
Tiene razón para el separador tanto en la parte de entrada como en la de salida. Definió separador como:
" "#
Hay dos comillas dobles, porque es más fácil capturar los dos números que desea (según su entrada de ejemplo).
(2) En /.* ([0-9] +) $ /, ¿$ significa el final de la cadena?
¡Exactamente!
(3) En el tercer argumento de gensub (), ¿cuál es la diferencia entre "g" y "G"? no hay diferencia entre G y g. Mira esto:
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.
Esto es de http://www.gnu.org/s/gawk/manual/html_node/String-Functions.html . puede leer para obtener un uso detallado de gensub.