Coba ini (melongo diperlukan).
awk '{a=gensub(/.*#([0-9]+)(\").*/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+\"/,a+11"\"",$0);}print $0}' YourFile
Uji dengan contoh Anda:
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"))
)
Perhatikan bahwa perintah ini tidak akan berfungsi jika dua angka (mis. 1 "dan" # 1 ") berbeda. Atau ada lebih banyak angka di baris yang sama dengan pola ini (mis. 23" ... 32 "..." # 123 ") dalam satu baris.
MEMPERBARUI
Karena @Tim (OP) mengatakan angka yang diikuti oleh "
dalam baris yang sama bisa berbeda, saya melakukan beberapa perubahan pada solusi saya sebelumnya, dan membuatnya berfungsi untuk contoh baru Anda.
BTW, dari contoh saya merasa itu bisa menjadi tabel struktur konten, jadi saya tidak melihat bagaimana dua angka itu bisa berbeda. Pertama adalah nomor halaman yang dicetak, dan yang kedua dengan # akan menjadi indeks halaman. Apakah saya benar?
Bagaimanapun, Anda tahu kebutuhan Anda yang terbaik. Sekarang solusi baru, masih dengan gawk (saya memecah perintah menjadi beberapa baris untuk membuatnya lebih mudah dibaca):
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
uji dengan contoh baru Anda :
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 berdasarkan komentar @Tim
(1) Apakah FS = OFS = "\" \ "#" berarti pemisah bidang dalam input dan output adalah kuotasi ganda, spasi, kuotasi ganda, dan #? Mengapa menentukan penawaran ganda dua kali?
Anda tepat untuk pemisah di bagian input dan output. Ini didefinisikan pemisah sebagai:
" "#
Ada dua tanda kutip ganda, karena lebih mudah untuk menangkap dua angka yang Anda inginkan (berdasarkan contoh input Anda).
(2) Dalam /.* ([0-9] +) $ /, apakah $ berarti akhir dari string?
Persis!
(3) Dalam argumen ketiga gensub (), apa perbedaan antara "g" dan "G"? tidak ada perbedaan antara G dan g. Lihat ini:
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.
Ini dari http://www.gnu.org/s/gawk/manual/html_node/String-Functions.html . Anda dapat membaca untuk mendapatkan detail penggunaan gensub.