ลองสิ่งนี้ (จำเป็นต้องใช้ gawk)
awk '{a=gensub(/.*#([0-9]+)(\").*/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+\"/,a+11"\"",$0);}print $0}' YourFile
ทดสอบกับตัวอย่างของคุณ:
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"))
)
โปรดทราบว่าคำสั่งนี้จะไม่ทำงานหากตัวเลขสองตัว (เช่น 1 "และ" # 1 ") แตกต่างกันหรือมีตัวเลขจำนวนมากในบรรทัดเดียวกันกับรูปแบบนี้ (เช่น 23" ... 32 "... " # 123 ") ในหนึ่งบรรทัด
UPDATE
เนื่องจาก @Tim (OP) กล่าวว่าหมายเลขที่ตามด้วย"
ในบรรทัดเดียวกันอาจแตกต่างกันฉันจึงทำการเปลี่ยนแปลงบางอย่างในโซลูชันก่อนหน้าของฉันและทำให้มันใช้ได้กับตัวอย่างใหม่ของคุณ
BTW จากตัวอย่างที่ฉันรู้สึกว่ามันอาจเป็นโครงสร้างของเนื้อหาดังนั้นฉันไม่เห็นว่าตัวเลขทั้งสองจะแตกต่างกันอย่างไร อันดับแรกคือหมายเลขหน้าที่พิมพ์และอันดับที่ 2 คือ # จะเป็นดัชนีหน้า ฉันถูกไหม?
อย่างไรก็ตามคุณรู้ว่าความต้องการของคุณดีที่สุด ตอนนี้โซลูชันใหม่ยังคงมีเพ่งพิศ (ฉันแบ่งคำสั่งเป็นบรรทัดเพื่อให้อ่านง่ายขึ้น):
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
ทดสอบด้วยตัวอย่างใหม่ของคุณ:
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ตามความคิดเห็นของ @Tim
(1) FS = OFS = "\" \ "#" หมายถึงตัวคั่นฟิลด์ในทั้งอินพุตและเอาต์พุตคือเครื่องหมายคำพูดคู่, ช่องว่าง, เครื่องหมายคำพูดคู่และ #? ทำไมต้องระบุเครื่องหมายคำพูดคู่สองครั้ง
คุณเหมาะสมกับตัวคั่นทั้งในส่วนของอินพุตและเอาต์พุต มันกำหนดคั่นเป็น:
" "#
มีเครื่องหมายคำพูดสองตัวเนื่องจากจะง่ายต่อการจับตัวเลขสองตัวที่คุณต้องการ (อิงจากอินพุตตัวอย่างของคุณ)
(2) ใน /.* ([0-9] +) $ /, $ หมายถึงจุดสิ้นสุดของสตริงหรือไม่?
แน่นอน!
(3) ในอาร์กิวเมนต์ที่สามของ gensub () อะไรคือความแตกต่างระหว่าง "g" และ "G" ไม่มีความแตกต่างระหว่าง G และ g ลองดู:
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.
นี้เป็นจากhttp://www.gnu.org/s/gawk/manual/html_node/String-Functions.html คุณสามารถอ่านเพื่อรับรายละเอียดการใช้งานของ gensub