การเรียนรู้คำสั่ง Linux: sed Sed - สวัสดี Linux Wiki การเรียนรู้คำสั่ง Linux: sed
และฉันไม่สามารถหาบทเรียนที่เขียนได้ดี
ให้ฉันบอกว่าฉันได้ทำงานกับ regex ในภาษาอื่น ๆ (Python, JavaScript, Java) เป็นแบบนี้ ไม่ควรเป็นปัญหา
ต่อไปนี้เป็นคำถามของฉัน (เชิงทฤษฎีและเชิงปฏิบัติมากกว่า):
นิพจน์ทั่วไปที่ใช้ใน sed เหมือนกับนิพจน์ทั่วไปที่ใช้ใน Python/JS/Java ทุกประการหรือไม่ ฉันเคยอ่านเกี่ยวกับ BRE และ ERE แล้ว แต่ต่างกันอย่างไร ไม่ควรจะเป็น การขยายตัวบรี?
ถ้าฉันต้องการพูดเพียงแค่แยกบางสิ่งออกจากเอาท์พุตไพพ์ไวยากรณ์ sed คืออะไร?
รายละเอียดเกี่ยวกับคำถามที่สอง: สมมติว่าฉันมีเอาต์พุตสถานะการออนไลน์ด้วย sed:
เวลาทำงาน | sed...
รับตัวอย่างผลลัพธ์จากสถานะการออนไลน์: 18:13 ถึง 5:12 ผู้ใช้ 2 ราย โหลดเฉลี่ย: 0.45 0.37 0.40 ฉันต้องการแยกวิเคราะห์สถานะการออนไลน์ครั้งเดียวเป็นตัวเลขสองตัวแยกกัน (ชั่วโมงและนาที) จากนั้นฉัน ฉันต้องการแสดง ในรูปแบบ xxhyym (xx – ชั่วโมง, ปปป นาที)
และสุดท้ายนี่คือสิ่งที่ฉันจะทำใน Python:
Hh, mm = re.match(r"\s+ up \s+(\d(1,2)):(\d(1,2))").groups() พิมพ์ "%sh%sm" % (hh , มม.)
2 โซลูชั่นรวบรวมเว็บฟอร์มสำหรับ “คำสั่งปกติและคำสั่งด้วยคำสั่ง sed”
เครื่องมือยูนิกซ์แบบดั้งเดิมรองรับ BRE หรือ ERE (นิพจน์ทั่วไปพื้นฐานหรือแบบขยาย) POSIX เข้ารหัสทั้งคู่ วิกิพีเดียอธิบายพวกเขา เครื่องมือที่ทันสมัยส่วนใหญ่จะขยาย ERE ซึ่งมักจะประกอบด้วย ฟังก์ชั่นเพิ่มเติมเปิดตัวครั้งแรกในภาษา Perl (ซึ่งรู้จักกันในชื่อ PCRE)
ERE ขยายฟังก์ชันการทำงานของ BRE แต่ไม่ขยายไวยากรณ์ ใน BRE เฉพาะอักขระ \[.*^$ เท่านั้นที่มีความหมายพิเศษ และตัวดำเนินการบางตัว เช่น การจัดกลุ่ม \(…\) ใช้แบ็กสแลช ใน ERE +?|() ก็ถือเป็นสิ่งพิเศษเช่นกัน และแบ็กสแลชที่ตามด้วยอักขระที่ไม่ใช่ตัวอักษรและตัวเลขจะไม่มีความพิเศษ
BRE ไม่มี Python/PCRE \d และ \s คุณสามารถแสดงชุดอักขระเหล่านี้ได้โดยใช้ชุดโครงสร้างและคลาสอักขระแบบดั้งเดิม: \d คือ [[:digit:]] และ \s คือ [[:space:]] สังเกตวงเล็บคู่: อันหนึ่งเพื่อระบุชุดอักขระและอีกอันเพื่อระบุคลาสอักขระ เช่น "ตัวอักษร ขีดกลาง หรือขีดล่าง" สามารถเขียนได้ [-_[:alpha:]]
BRE ไม่มีตัวดำเนินการ + (การใช้งาน sed บางตัวรองรับ \+ เป็นส่วนขยายของไวยากรณ์ BRE) X+ เหมือนกับ XX* กลุ่มและการแข่งขันจำเป็นต้องมีเครื่องหมายแบ็กสแลชเพิ่มเติม
ดังนั้น BRE ที่เทียบเท่ากับ \s+ up \s+(\d(1,2)):(\d(1,2)) ของ Python คือ [[:space:]][[:space:]]* up [[: ช่องว่าง:]][[:space:]]*\([[:digit:]]\(1,2\)\):\([[:digit:]]\(1,2\)\) โปรดทราบว่าคุณกำลังใช้งานมากเกินไป: \s+ และช่องว่างหมายถึงอักขระช่องว่างอย่างน้อยสองตัว
คุณจะต้องจับคู่ทั้งบรรทัด เนื่องจากคำสั่ง sed จะเขียนบรรทัดใหม่ ไม่มีคำสั่งแยกต่างหากสำหรับการเขียนสตริงที่รวบรวมจากกลุ่มที่บันทึกไว้ การแก้ไขช่องว่างเพิ่มเติมซึ่งเทียบเท่ากับข้อมูลโค้ด Python ของคุณ:
เวลาทำงาน | sed "s/^.*[[:space:]][[:space:]]*up[[:space:]][[:space:]]*\([[:digit:]]\(1 ,2\)\):\([[:หลัก:]]\(1,2\)\).*$/\1h\2m/"
ต่างจากตัวอย่าง Python ตรงที่จะดึงข้อมูลนัดแรกมากกว่านัดสุดท้าย แต่นั่นไม่สำคัญที่นี่
เอาต์พุตสถานะการออนไลน์ประกอบด้วยอักขระเว้นวรรคและหลัก ASCII ดังนั้นคุณจึงสามารถลดความซับซ้อนของ regex ได้:
เวลาทำงาน | sed "s/^.* ขึ้น *\(\(1,2\)\):\(\(1,2\)\).*$/\1h\2m/"
ซึ่งจะสอดคล้องกับเวลาทำงานในช่วงสุดสัปดาห์หากเครื่องมีอายุน้อยกว่า 1 วันเท่านั้น ฉันจะทิ้งจำนวนวันที่เหมาะสมไว้เป็นแบบฝึกหัด (คำแนะนำ: เขียนสองสำนวน: sed -es/AS ABOVE/\1h\2m/ -e "s/EXERCISE/\1d\2h\3m/")
เครื่องมือแต่ละอันใช้ (ส่วนใหญ่) ไลบรารี RE ของตัวเอง แม้กระทั่งในหมู่ รุ่นที่แตกต่างกัน sed คุณจะพบความแตกต่างที่นี่ สองมาตรฐานยอดนิยม - มาตรฐานปกติ นิพจน์ POSIXซึ่งหลายชุดยอมรับ (อย่างน้อยก็มีบางตัวเลือก) อีกชุดยอดนิยมคือไลบรารี Perl Compatible Regular Expression (PCRE) แต่อย่างหลังจะแตกต่างจาก “วานิลลา” เล็กน้อย RE...
ในกรณีของคุณ:
เวลาทำงาน | sed -e "s/^ \(\):\(\).*$/\1h\2m/"
(ลองใช้ Fedora 18, sed-4.2.1-10.fc18.x86_64, GNU sed)
อัปเดต:เกิดอะไรขึ้นกับเอกสารขนาดใหญ่ หน้าแรก GNU sed? หรือบทช่วยสอนนี้? เอกสารไวท์เปเปอร์สำหรับ GNU sed ยาวนิดหน่อยแต่ครบถ้วน
โปรแกรมแก้ไข sed stream เป็นโปรแกรมแก้ไขข้อความแบบไม่โต้ตอบที่ดำเนินการกับข้อมูลที่มาจากอินพุตมาตรฐานหรือจากไฟล์ Sed แก้ไขข้อมูลทีละบรรทัด
มีการอธิบายพื้นฐานของการทำงานกับโปรแกรมแก้ไข sed คู่มือเล่มนี้ครอบคลุมถึงเทคนิคขั้นสูงเพิ่มเติม
การรวมทีม
บางครั้งจำเป็นต้องส่งคำสั่งหลายคำสั่งไปยัง sed editor พร้อมกัน ทำได้หลายวิธี
หากคุณยังไม่มีไฟล์ทดสอบสำหรับการทำงานกับ sed ให้สร้างสภาพแวดล้อมต่อไปนี้:
ซีดี
cp /usr/share/common-licenses/BSD
cp /usr/share/common-licenses/GPL-3 .
echo “นี่คือเพลงที่ไม่มีวันจบสิ้น”
ไม่รู้ว่ามันคืออะไร
เพียงเพราะว่า..." >น่ารำคาญ.txt
เนื่องจาก sed ทำงานบนอินพุตและเอาต์พุตมาตรฐาน คุณจึงสามารถเรียกคำสั่ง sed ต่างๆ พร้อมกันในบรรทัดเดียวได้:
sed "s/และ/\&/"น่ารำคาญ.txt | sed "s/คน/ม้า/"
ใช่ มันดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
ม้าบางตัวก็เริ่มร้องเพลง
ไม่รู้ว่ามันคืออะไร
และพวกเขาจะร้องเพลงนี้ต่อไปตลอดไป
เพียงเพราะ...
วิธีนี้จะได้ผล แต่การเรียก sed หลายครั้งจะสร้างค่าใช้จ่าย ใช้พื้นที่มากขึ้น และไม่ใช้ประโยชน์จากความสามารถในตัวของ sed
คุณสามารถส่งหลายคำสั่งไปยัง sed พร้อมกันได้โดยใช้ตัวเลือก –e ซึ่งต้องแทรกก่อนแต่ละคำสั่ง:
sed -e "s/และ/\&/" -e "s/people/horses/"น่ารำคาญ.txt
คุณยังสามารถเชื่อมคำสั่งเข้ากับสตริงโดยใช้อักขระอัฒภาคได้ วิธีนี้ใช้ได้ผลเหมือนกับวิธีก่อนหน้าทุกประการ
sed "s/and/\&/;s/people/horses/"น่ารำคาญ.txt
โปรดทราบว่าการใช้แฟล็ก -e จำเป็นต้องทำลายเครื่องหมายคำพูดเดี่ยว แต่การใช้เครื่องหมายอัฒภาคจะทำให้คำสั่งทั้งหมดแสดงรายการภายในเครื่องหมายคำพูดเดี่ยวได้
วิธีการเรียกหลายคำสั่งพร้อมกันทั้งสองวิธีนี้ค่อนข้างสะดวก แต่มีบางครั้งที่คุณต้องใช้บรรทัดคำสั่งง่ายๆ
คุณควรจะคุ้นเคยกับตัวดำเนินการ = ด้วย คำสั่งนี้จะแทรกหมายเลขบรรทัดระหว่างแต่ละบรรทัดที่มีอยู่ ผลลัพธ์มีลักษณะดังนี้:
sed "="น่ารำคาญ.txt
1
นี่คือเพลงที่ไม่สิ้นสุด
2
ใช่ มันดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
3
บางคนเริ่มร้องเพลงนี้
4
ไม่รู้ว่ามันคืออะไร
5
และพวกเขาจะร้องเพลงนี้ต่อไปตลอดไป
6
เพียงเพราะ...
ตอนนี้ให้ลองแก้ไขข้อความเพื่อทำความเข้าใจว่ารูปแบบลำดับเลขเปลี่ยนแปลงไปอย่างไร
คำสั่ง G ตามค่าเริ่มต้นจะเพิ่มบรรทัดว่างระหว่างบรรทัดที่มีอยู่
sed "G" ที่น่ารำคาญ.txt
_
นี่คือเพลงที่ไม่สิ้นสุด
_
ใช่ มันดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
_
บางคนเริ่มร้องเพลงนี้
_
ไม่รู้ว่ามันคืออะไร
_
และพวกเขาจะร้องเพลงนี้ต่อไปตลอดไป
_
เพียงเพราะ...
ลองรวมสองคำสั่งนี้เข้าด้วยกัน ในตอนแรกอาจปรากฏว่าเอาต์พุตของคำสั่งเหล่านี้จะมีบรรทัดว่างระหว่างบรรทัดข้อความและบรรทัดที่มีตัวเลข อย่างไรก็ตามผลลัพธ์จะมีลักษณะดังนี้:
sed "=;G" ที่น่ารำคาญ.txt
1
นี่คือเพลงที่ไม่สิ้นสุด
_
2
ใช่ มันดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
_
3
บางคนเริ่มร้องเพลงนี้
_
4
ไม่รู้ว่ามันคืออะไร
. . .
. . .
สิ่งนี้เกิดขึ้นเนื่องจากตัวดำเนินการ = แก้ไขสตรีมเอาต์พุต (ซึ่งหมายความว่าเอาต์พุตผลลัพธ์ไม่สามารถใช้สำหรับการแก้ไขเพิ่มเติมได้)
สิ่งนี้สามารถแก้ไขได้โดยใช้การเรียก sed สองครั้ง โดยที่การโทรครั้งแรกจะถือเป็นข้อความธรรมดาไปยังการโทรครั้งที่สอง
sed "="น่ารำคาญ.txt | sed "จี"
1
_
นี่คือเพลงที่ไม่สิ้นสุด
_
2
_
ใช่ มันดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
_
3
_
บางคนเริ่มร้องเพลงนี้
. . .
. . .
โปรดทราบว่าคำสั่งบางคำสั่งทำงานในลักษณะเดียวกัน โดยเฉพาะอย่างยิ่งหากคุณรวมหลายคำสั่งเข้าด้วยกันและผลลัพธ์ออกมาแตกต่างไปจากที่คาดไว้
ที่อยู่ขั้นสูง
ข้อดีอย่างหนึ่งของคำสั่ง addressing-aware ของ sed ก็คือ สามารถใช้นิพจน์ทั่วไปเป็นเกณฑ์ได้ ซึ่งหมายความว่าคุณสามารถทำงานกับไฟล์ที่ไม่ทราบเนื้อหาแน่ชัดได้
sed "1,3s/.*/Hello/"น่ารำคาญ.txt
สวัสดี
สวัสดี
สวัสดี
ไม่รู้ว่ามันคืออะไร
และพวกเขาจะร้องเพลงนี้ต่อไปตลอดไป
เพียงเพราะ...
แต่คุณสามารถใช้นิพจน์ทั่วไปที่จับคู่เฉพาะบรรทัดที่มีรูปแบบเฉพาะแทนได้ ในการดำเนินการนี้ คุณจะต้องวางรูปแบบการค้นหาระหว่างเครื่องหมายทับ 2 ตัว (/) ก่อนคำสั่ง
sed "/singing/s/it/& เสียงดัง/"น่ารำคาญ.txt
นี่คือเพลงที่ไม่สิ้นสุด
ใช่ มันดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
บางคนเริ่มร้องเพลงเสียงดัง
ไม่รู้ว่ามันคืออะไร
และพวกเขาจะร้องเพลงนี้ต่อไปอย่างดังตลอดไป
เพียงเพราะ...
ตัวอย่างนี้วางคำไว้หน้าคำแรกในทุกบรรทัดที่มีคำว่าร้องเพลง โปรดทราบว่าบรรทัดที่สองและสี่จะไม่เปลี่ยนแปลงเนื่องจากไม่ตรงกับรูปแบบ
การระบุที่อยู่ของนิพจน์สามารถทำให้ซับซ้อนมากขึ้นได้ ทำให้ทีมมีความยืดหยุ่นมากขึ้น
ตัวอย่างต่อไปนี้สาธิตวิธีการใช้นิพจน์ทั่วไปเพื่อสร้างที่อยู่สำหรับคำสั่งอื่นๆ คำสั่งนี้จะค้นหาทุกสิ่ง เส้นว่างและลบออก:
sed "/^$/d" GPL-3
ใบอนุญาตสาธารณะทั่วไปของ GNU
ฉบับที่ 3, 29 มิถุนายน 2550
ลิขสิทธิ์ (C) 2007 Free Software Foundation, Inc.
ทุกคนได้รับอนุญาตให้คัดลอกและแจกจ่ายสำเนาคำต่อคำ
ของเอกสารใบอนุญาตนี้แต่ไม่อนุญาตให้เปลี่ยนแปลง
คำนำ
GNU General Public License เป็นใบอนุญาตลิขสิทธิ์ฟรีสำหรับ
. . .
. . .
โปรดทราบว่าสามารถใช้นิพจน์ทั่วไปได้ทุกที่ในช่วง
ตัวอย่างเช่น คุณสามารถลบบรรทัดระหว่างบรรทัด START และ END:
sed "/^START$/,/^END$/d" ไฟล์อินพุต
โปรดทราบว่าคำสั่งนี้จะลบบรรทัดทั้งหมดตั้งแต่คำแรก START ที่พบ จนถึงคำแรก END ที่พบ และหากพบคำว่า START อีกครั้ง ก็จะลบข้อมูลต่อไป
หากต้องการกลับที่อยู่ (นั่นคือ เลือกบรรทัดที่ไม่ตรงกับรูปแบบ) ให้ใช้เครื่องหมายอัศเจรีย์ (!)
ตัวอย่างเช่น หากต้องการลบบรรทัดที่กรอก คุณต้องป้อน:
sed "/^$/!d" GPL-3
ที่อยู่ไม่จำเป็นต้องเป็นนิพจน์ที่ซับซ้อนจึงจะกลับด้านได้ การผกผันทำงานในลักษณะเดียวกันกับการกำหนดหมายเลขปกติ
การใช้บัฟเฟอร์เพิ่มเติม
บัฟเฟอร์การพักเพิ่มเติมเพิ่มความสามารถของ sed ในการดำเนินการแก้ไขหลายบรรทัด
บัฟเฟอร์เพิ่มเติมคือพื้นที่เก็บข้อมูลชั่วคราวที่สามารถแก้ไขได้ด้วยคำสั่งบางอย่าง
การมีบัฟเฟอร์พิเศษนี้จะทำให้คุณสามารถจัดเก็บสตริงในขณะที่คุณทำงานกับสตริงอื่นๆ ได้
คำสั่งสำหรับการทำงานกับบัฟเฟอร์:
- h: คัดลอกบัฟเฟอร์การประมวลผลปัจจุบัน (บรรทัดสุดท้ายที่ตรงกันที่คุณกำลังทำงานอยู่) ไปยังบัฟเฟอร์เพิ่มเติม
- H: เพิ่มบัฟเฟอร์การประมวลผลปัจจุบันที่จุดสิ้นสุดของปัจจุบัน การประมวลผลเพิ่มเติมโดยคั่นด้วยอักขระ \n
- g: คัดลอกบัฟเฟอร์ย่อยปัจจุบันไปยังบัฟเฟอร์การประมวลผลปัจจุบัน บัฟเฟอร์การประมวลผลก่อนหน้านี้จะหายไป
- G: เพิ่มเทมเพลตปัจจุบันให้กับบัฟเฟอร์การประมวลผลปัจจุบัน โดยคั่นด้วยอักขระ \n
- x: สลับเทมเพลตปัจจุบันและบัฟเฟอร์เพิ่มเติม
ไม่สามารถประมวลผลเนื้อหาของบัฟเฟอร์เพิ่มเติมได้จนกว่าจะถูกย้ายไปยังบัฟเฟอร์การประมวลผล
ลองดูตัวอย่างที่ซับซ้อน
ลองเชื่อมบรรทัดที่อยู่ติดกันโดยใช้คำสั่งต่อไปนี้:
sed -n "1~2h;2~2(H;g;s/\n/ /;p)" น่ารำคาญ.txt
บันทึก: อันที่จริง sed เสนอคำสั่ง N ในตัวแยกต่างหากสำหรับสิ่งนี้ แต่สำหรับการปฏิบัติการพิจารณาตัวอย่างนี้มีประโยชน์
ตัวเลือก –n ระงับเอาต์พุตอัตโนมัติ
1~2h – คำจำกัดความของที่อยู่ ดำเนินการแทนที่ทุกบรรทัดที่สองของข้อความตามลำดับ โดยเริ่มจากบรรทัดแรก (นั่นคือ บรรทัดคี่ทุกบรรทัด) คำสั่ง h คัดลอกบรรทัดที่ตรงกันไปยังบัฟเฟอร์เพิ่มเติม
ทีมที่เหลือรับเข้ามา วงเล็บปีกกา- ซึ่งหมายความว่าส่วนนี้ของคำสั่งจะสืบทอดที่อยู่ที่เพิ่งระบุไว้ หากไม่มีวงเล็บเหล่านี้ เฉพาะคำสั่ง H เท่านั้นที่จะสืบทอดที่อยู่ และคำสั่งที่เหลือจะถูกดำเนินการแบบต่อบรรทัด
แน่นอนว่า N บิวอินที่กล่าวถึงก่อนหน้านี้นั้นสั้นกว่าและง่ายกว่ามากและให้ผลลัพธ์เหมือนเดิม:
sed -n "N;s/\n/ /p"น่ารำคาญ.txt
นี่คือเพลงที่ไม่สิ้นสุด ใช่ มันจะดำเนินต่อไปเรื่อยๆ เพื่อนของฉัน
บางคนเริ่มร้องเพลงนี้โดยไม่รู้ว่าเพลงอะไร
และพวกเขาจะร้องเพลงนี้ต่อไปตลอดไปเพียงเพราะว่า...
สคริปต์ sed
คำสั่งสามารถรวบรวมเป็นสคริปต์ได้ สิ่งนี้ทำให้คุณสามารถดำเนินการชุดคำสั่งทั้งชุดบนเทมเพลตเป้าหมายเดียว
ตัวอย่างเช่น คุณสามารถเขียนสคริปต์เพื่อสร้างข้อความธรรมดาที่ต้องจัดรูปแบบล่วงหน้าได้
จากนั้นคุณจะไม่ต้องทำซ้ำคำสั่งเดิมซ้ำๆ ในแต่ละข้อความ โดยพื้นฐานแล้ว sed script คือรายการคำสั่งที่ต้องใช้กับอ็อบเจ็กต์ที่กำหนด
ตัวอย่างเช่น:
s/นี่/นั่น/ก
s/หิมะ/ฝน/g
1.5s/ไพน์โคน/แอปริคอท/กรัม
จากนั้นคุณสามารถเรียกไฟล์:
sed -f sedScriptName ไฟล์ ToEdit
บทสรุป
ตอนนี้คุณรู้เทคนิคขั้นสูงเพิ่มเติมในการทำงานกับ sed แล้ว
ในตอนแรก คำสั่ง sed นั้นเข้าใจยากและสับสนได้ง่าย ดังนั้นจึงแนะนำให้ทดลองก่อนนำไปใช้กับข้อมูลสำคัญ
แท็ก: ,คุณประโยชน์ sedเป็นโปรแกรมแก้ไขข้อความสตรีมมิ่งที่ทรงพลังพร้อมรองรับนิพจน์ทั่วไป โดยการใช้ sedคุณสามารถแทนที่เทมเพลตข้อความ (และในไฟล์โดยตรง!) ลบบรรทัด (องค์ประกอบอาร์เรย์) บรรทัดเอาต์พุตที่ตรงกับมาสก์ (คล้ายกับ เกรป- บรรณาธิการ sedรองรับการใช้หลายคำสั่งและไวยากรณ์นิพจน์ทั่วไปแบบขยาย (ซึ่งไม่จำเป็นต้องมีการหลีกอักขระพิเศษ)
sed ไม่รองรับการตรวจสอบไปข้างหน้าและย้อนกลับใน regex! หากต้องการแทนที่โดยใช้ไวยากรณ์ regex แบบขยายให้ใช้:
ความสนใจ!
การทำงานกับอักขระขึ้นบรรทัดใหม่ค่อนข้างเป็นปัญหา! ทางออกที่สะดวกที่สุดคือ:
คุณสามารถใช้สัญลักษณ์ใดก็ได้เป็นตัวคั่น (เช่น ,) จับคู่ส่วนต่างๆ (ซึ่งอยู่ในวงเล็บ) มีให้เป็น .
ตัวเลือกยูทิลิตี้:
ธงบรรทัดคำสั่ง (ระบุที่ส่วนท้ายของมาสก์):
ตัวอย่าง
การกรองแถว
พิมพ์บรรทัดที่ 1-5:
ไฟล์เอาต์พุตที่ตรงกับมาสก์:
บรรทัดที่ยาวเกิน 80 ตัวอักษร:
แทนที่ด้วยเทมเพลต
จำนวนการพิมพ์ ( ไม้ขีด) ผ่านการจัดตาราง:
แทนที่ชื่อไฟล์ ( นักแต่งเพลงบน นักแต่งเพลง-dev):
แทนที่อักขระ (regex):
แทนที่ URL ในไฟล์ (สิ่งที่อยู่ในตัวคั่นและสำหรับการแทนที่ในไฟล์):
แทนที่พารามิเตอร์ในการกำหนดค่า:
ลบช่องว่างนำหน้า (คล้ายกับ ลิทริม):
การลบแถว
ลบบรรทัดที่ตรงกับรูปแบบออกจากไฟล์:
ลบบรรทัดแรกของเอาต์พุต:
ลบบรรทัดตั้งแต่แรกถึงที่เกี่ยวข้อง นิพจน์ทั่วไป:
แทนที่สตริงย่อย:
บันทึก
โดยค่าเริ่มต้น พิเศษทั้งหมดจะต้องเป็น Escape อักขระใน regexes ซึ่งทำให้อ่านมาสก์ยากมาก หากต้องการหลีกเลี่ยงอักขระพิเศษเฉพาะเมื่อมีการอธิบายไว้ในข้อความ ให้เปิดใช้งานโหมดขั้นสูง นิพจน์ทั่วไปการแสดงออกโดยใช้ตัวเลือก
ลบบรรทัดว่าง:
ลบอักขระ N=2 ตัวสุดท้าย:
การสกัดสตริงย่อย
ตัด / จำอักขระ N=4 ตัวสุดท้าย:
#sed, #regexp, #bash
การเรียนรู้คำสั่ง Linux: sed
สตรีมมิ่งโปรแกรมแก้ไข SED
Sed เป็นเครื่องมือน้ำหนักเบา (ไบนารีมีน้ำหนักเพียง 128 กิโลไบต์) และเครื่องมือประมวลผลข้อความที่สะดวก
ในบทความนี้ฉันจะให้หลายอย่าง ตัวอย่างง่ายๆใช้ sedและบอกคุณเกี่ยวกับความสามารถหลัก ๆ ของมัน
Sed รับอินพุตสตรีมหรือไฟล์ทีละบรรทัด แก้ไขแต่ละบรรทัดตามกฎที่กำหนดไว้ในสคริปต์ sed จากนั้นจึงส่งออกผลลัพธ์ Sed เป็นภาษาโปรแกรมที่สมบูรณ์ของทัวริง
รูปแบบคำสั่ง sed
คำสั่ง sed มีรูปแบบ:
sed [ -n ] [ -e สคริปต์ ] [ -f ไฟล์สคริปต์ ] [ ไฟล์ ]ธง -nระงับการส่งออก
-e- ชี้ไปที่รายการคำสั่งที่ระบุใน บรรทัดคำสั่ง.
-ฉ- ระบุตำแหน่งของไฟล์สคริปต์
แก้ไขรูปแบบคำสั่ง
ไฟล์สคริปต์ประกอบด้วยชุดคำสั่ง:
[ ที่อยู่ [ , ที่อยู่ ] ] คำสั่ง [ อาร์กิวเมนต์ ]หนึ่งรายการในแต่ละบรรทัด
ที่อยู่เป็นหมายเลขบรรทัดหรือ อักขระพิเศษหรือนิพจน์ทั่วไป:
$
- บรรทัดสุดท้าย
เริ่ม~น- แต่ละ เอ็น-บรรทัดที่เริ่มต้นจากหมายเลข เริ่ม
/การแสดงออกปกติ/- เส้นที่อยู่ภายใต้ Regular_expression
ตัวอย่าง:
- หากไม่มีการระบุที่อยู่ บรรทัดทั้งหมดจะถูกประมวลผล
- หากมีการระบุที่อยู่หนึ่งรายการ บรรทัดที่เกี่ยวข้องจะถูกประมวลผล
- หากมีการระบุที่อยู่สองรายการ ระบบจะเลือกบรรทัดในช่วงเวลาที่ระบุ
- !ทีม- ดำเนินการ ทีมสำหรับแถวที่ไม่ได้เลือกตามที่อยู่
คำสั่งพื้นฐาน
ลองดูคำสั่งพื้นฐาน:
[ที่อยู่] ข้อความ- เพิ่มบรรทัดใหม่พร้อมข้อความหลังบรรทัดที่ระบุ
[ที่อยู่ [, ที่อยู่]] คข้อความ- ลบบรรทัดที่เลือกและแทนที่ด้วย ข้อความ
[ที่อยู่ [, ที่อยู่]] ง- ลบบรรทัดที่ระบุ
[ที่อยู่] ฉันส่งข้อความ- แทรก ข้อความแทนบรรทัดที่ระบุ
[ที่อยู่ [, ที่อยู่]] น(พร้อมธง. -n) แสดงบรรทัดที่พบ
[ที่อยู่]ถาม- ออกจาก sed
[ที่อยู่ [, ที่อยู่]] r ไฟล์- อ่าน ไฟล์และส่งออกเนื้อหา
[ที่อยู่ [, ที่อยู่]] s/regex/replacement/flags- แทนที่ การแสดงออกปกติบน ทดแทน-y โดยคำนึงถึงแฟล็กของบัญชี:
- g - ในทั้งบรรทัด
- ฉัน - ไม่คำนึงถึงขนาดตัวพิมพ์
- p - แสดงผลการแทนที่
[ที่อยู่ [, ที่อยู่]] y/line1/line2/- แทนที่เหตุการณ์ทั้งหมดของตัวละครใน บรรทัดที่ 1สัญลักษณ์ที่สอดคล้องกันจาก เส้น2.
ความยาวของเส้นจะต้องเท่ากัน
[ที่อยู่[,ที่อยู่]] (คำสั่ง)- คำสั่งกลุ่มวงเล็บ
[ที่อยู่] =- ให้หมายเลขบรรทัด
แท็ก
: ฉลาก- จับคู่กับกลุ่มคำสั่ง ฉลาก
ข มาร์ค ฉลาก, ถ้า ฉลากหายไปแล้วไปต่อท้ายไฟล์คำสั่ง
ฉลาก- ไปที่คำสั่งที่ระบุโดยฉลาก ฉลากหลังจากการแทนที่สำเร็จโดยใช้คำสั่งเท่านั้น s///
การดำเนินการวนซ้ำ
sed ทำงานร่วมกับบัฟเฟอร์ข้อมูลสองตัว: บัฟเฟอร์หลักและบัฟเฟอร์เสริม เริ่มแรกบัฟเฟอร์ทั้งสองว่างเปล่า
การทำงานกับบัฟเฟอร์เหล่านี้ดำเนินการโดยใช้คำสั่ง:\\`h', `H', `x', `g', `G' `D' ชม.- แทนที่เนื้อหาของบัฟเฟอร์เสริมด้วยเนื้อหาของบัฟเฟอร์หลัก
ชม- ผนวกบรรทัดใหม่เข้ากับบัฟเฟอร์เสริมแล้วผนวกเนื้อหาของบัฟเฟอร์หลักเข้ากับเนื้อหาของบัฟเฟอร์เสริม
x- สลับเนื้อหาของบัฟเฟอร์ทั้งสอง
ก- แทนที่เนื้อหาของบัฟเฟอร์หลักด้วยเนื้อหาของบัฟเฟอร์เสริม
ช- ผนวกบรรทัดใหม่เข้ากับบัฟเฟอร์หลัก จากนั้นจึงผนวกเนื้อหาของบัฟเฟอร์เสริมเข้ากับเนื้อหาของบัฟเฟอร์หลัก
ดี- ลบข้อความบัฟเฟอร์หลักจนถึงอักขระขึ้นบรรทัดใหม่ถัดไป
เอ็น- ผนวกบรรทัดใหม่เข้ากับบัฟเฟอร์หลัก จากนั้นเพิ่มบรรทัดถัดไปที่จะประมวลผล
ป- พิมพ์เนื้อหาของบัฟเฟอร์หลักจนถึงอักขระขึ้นบรรทัดใหม่ถัดไป
ตัวอย่างที่ซับซ้อนมากขึ้น
สคริปต์ต่อไปนี้สลับบรรทัดของไฟล์ (บรรทัดแรกกลายเป็นบรรทัดสุดท้ายและในทางกลับกัน)
เรานับบรรทัดของไฟล์ (เราแสดงจำนวนบรรทัดสุดท้าย)
ผลลัพธ์
การกลับรายการสตริง
สคริปต์นี้ย้ายตัวอักษรสองตัวพร้อมกัน
ข้อมูลเพิ่มเติม
คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับรูปแบบของสคริปต์ sed ได้โดยการอ่านคู่มือ ผู้ชายเซดหรือเอกสารทางเทคนิค ข้อมูล sed.
กลับไปที่เนื้อหา
02.02.2013
การขยายสตริงโดยใช้ Bash ในตัวอย่าง (การขยายพารามิเตอร์)
(วัสดุที่ใช้ [ 1] [ 2] และ [ 3])
หากต้องการทำงานกับสตริงโดยใช้ Bash ให้ใช้พารามิเตอร์ส่วนขยาย ( การขยายพารามิเตอร์) คำอธิบายของหลักการนี้สามารถพบได้ในย่อหน้า
คำอธิบายค่อนข้างเข้าใจยาก การเข้าใจหลักการทำงานพร้อมตัวอย่างง่ายกว่ามาก
1. การลบอักขระที่จุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด
อักขระตัวเดียวใด ๆ จะแสดงเป็น
มาตั้งค่าตัวแปรกัน
$ STRING=aabbcc $ echo $(STRING) aabbcc หากต้องการลบอักขระที่จุดเริ่มต้นของบรรทัด ให้ใช้คำสั่ง: $ echo $(STRING#?) abbcc $ echo $(STRING#???) bcc เพื่อลบอักขระที่ตำแหน่ง สิ้นสุดบรรทัด: $ echo $ (STRING%?) aabbc $ echo $(STRING%???) aab เพื่อจดจำว่าเมื่อใดควรใช้เครื่องหมาย และเมื่อใดควรใช้วิธีดั้งเดิมนี้:
อักขระจะถูกจัดเรียงตามลำดับบนแป้นพิมพ์และ:
- ทางซ้ายของ หมายถึง จากต้นบรรทัด
- ทางด้านขวาของ หมายถึง ไปจนถึงจุดสิ้นสุดของบรรทัด
2. การลบนิพจน์ทั่วไปที่จุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด
นิพจน์ทั่วไป (หรือ RegExp, regex) คือสตริงเทมเพลตหรือ "มาสก์" ที่ระบุกฎการค้นหา
มาตั้งค่าตัวแปรกันใหม่อีกครั้ง
$ STRING=GNULinux $ echo $(STRING) GNULinux ลบนิพจน์ทั่วไปที่จุดเริ่มต้นของบรรทัด: $ echo $(STRING#GNU) Linux ลบนิพจน์ทั่วไปที่ท้ายบรรทัด: $ echo $(STRING%Linux) GNU ตอนนี้เหมือนกัน แต่ใช้ " *" (เครื่องหมายดอกจัน)
ลบนิพจน์ทั่วไปที่จุดเริ่มต้นของบรรทัด (): $ echo $(STRING#*U) Linux ลบนิพจน์ทั่วไปที่ท้ายบรรทัด (): $ echo $(STRING%L*) GNU
การใช้งาน การแสดงออกปกติสามารถรวมกับ "?" (เครื่องหมายของสัญลักษณ์ใด ๆ ) ():
$ echo $(STRING%??n*) GNU
3. การใช้ ## และ %% สองเท่า
หากเมื่อลบออกจากบรรทัด การแสดงออกปกติ(*regex หรือ regex*) เมื่อใช้ “#” และ “%” กับ “*” - การลบจะเกิดขึ้นก่อนจะเกิดขึ้นครั้งแรก การแสดงออกปกติจากนั้นเมื่อใช้สองครั้ง “##” และ “%%” - ไปที่สุดท้าย:
และมาตั้งค่าตัวแปรอีกครั้ง
$ STRING=abcdcba $ echo $(STRING) abcdcba STRING=abcdcba $(STRING#*c) ดีซีบีเอ$(STRING##*ค) บริติชแอร์เวย์$(STRING%ค*) เอบีซีดี$(STRING%%c*) เกี่ยวกับ$ echo $(STRING#*c) dcba $ echo $(STRING##*c) ba $ echo $(STRING%c*) abcd $ echo $(STRING%%c*) ab
4.
แผ่นโกงสำหรับ sed
ค้นหาและแทนที่
แทนที่การเกิดขึ้นครั้งแรก
การทดแทนระดับโลก
$ STRING="abracadabra" $ echo "$(STRING/a/O)" Obracadabra $ echo "$(STRING//a/O)" ObrOcOdObrO $ echo "$(STRING/#a/O)" Obracadabra $ echo " $(STRING/%a/O)" abracadabrO $ echo "$(STRING/a/)" bracadabra $ echo "$(STRING//a/)" brcdbr
5. แยกสตริงย่อยโดยใช้ออฟเซ็ตและความยาว
ออฟเซ็ตจากขอบเส้น
ความยาวสตริงย่อย
5.1 อคติต่อค่าบวก
สำหรับค่าออฟเซ็ตที่เป็นบวก อักขระตัวแรกของบรรทัดจะสอดคล้องกับค่า ""
ตัวอย่างที่มีค่าบวก: $ STRING="Debian Gentoo RedHat" $ echo $(STRING:0:6) Debian $ echo $(STRING:14) RedHat $ echo $(STRING:7:6) Gentoo
5.2 ออฟเซ็ตสำหรับค่าลบ
สำหรับค่าลบ การนับจะดำเนินการจากท้ายบรรทัด และอักขระตัวสุดท้ายของบรรทัดสอดคล้องกับค่าเท่ากับ ""
หากต้องการเขียนออฟเซ็ตเชิงลบระหว่างเครื่องหมายทวิภาคและเครื่องหมายลบ คุณต้องเว้นวรรคหรือใส่ค่าลบในวงเล็บ
หากไม่ได้ระบุ ความยาวของสตริงย่อยจะถูกขยายไปจนถึงจุดสิ้นสุดโดยอัตโนมัติ
ตัวอย่างที่มีค่าลบ: $ STRING="Debian Gentoo RedHat" $ echo $(STRING: -6) RedHat $ echo $(STRING:(-6)) RedHat $ echo $(STRING:(-6):3) Red $ echo $(STRING:(-6):10) # ยาวเกินออฟเซ็ต RedHat
5.3 ค่าลบ
หากรับค่าลบ จะทำหน้าที่เป็นออฟเซ็ตจากจุดสิ้นสุดของสตริง ผลลัพธ์จะเป็นสตริงย่อยระหว่างออฟเซ็ตที่หนึ่งและที่สอง:
$ STRING=”Debian Gentoo RedHat” $ echo $(STRING:7:-7) Gentoo $ echo $(STRING:(-14):-7) Gentoo
วิธีนำทั้งหมดนี้ไปปฏิบัติ:
ด้านล่างนี้คือตัวเลือกโค้ดต่างๆ สำหรับการเปลี่ยนนามสกุลจากเป็นเมื่อแปลงไฟล์เสียงเป็นชุด: สำหรับ i ใน *.wav; ทำง่อย "$i" "$(i%???)mp3"; เสร็จแล้ว; สำหรับฉันใน *.wav; ทำง่อย "$i" "$(i%wav)mp3"; เสร็จแล้ว; สำหรับฉันใน *.wav; ทำง่อย "$i" "$(i%.*).mp3"; เสร็จแล้ว; สำหรับฉันใน *.wav; ทำง่อย "$i" "$(i/wav/mp3)"; เสร็จแล้ว; สำหรับฉันใน *.wav; ทำง่อย "$i" "$(i:0:-3)mp3"; เสร็จแล้ว;
6. การนับจำนวนตัวอักษรในบรรทัด
$ STRING="นับจำนวนอักขระในสตริง" $ echo $(#STRING) 36
ค้นหาจำนวนอักขระในไฟล์: $ ARRAY=(`cat file.html`) $ echo $(#ARRAY[@]) 1158
ควรสังเกตว่าไฟล์นี้ไม่ได้อ่านเฉพาะในตัวแปรเท่านั้น แต่ยังอ่านในอาร์เรย์ด้วย เนื่องจากประกอบด้วยหลายบรรทัด ดังนั้นเพื่อการคำนวณที่ถูกต้องจึงจำเป็นต้องเดิมพัน หากยังไม่เสร็จสิ้น คำสั่งจะอ่านเฉพาะบรรทัดแรกจากไฟล์:
$ ARRAY=(`cat file.html`) $ echo $(#ARRAY) 7 แน่นอนว่าบรรทัดแรกมีเพียงแท็กและอักขระขึ้นบรรทัดใหม่ของ Windows () - และนั่นคือ 7 ตัวอักษร
7. การเปลี่ยนตัวพิมพ์ของตัวละคร
แปลงอักขระตัวแรกเป็นตัวพิมพ์ใหญ่
แปลงอักขระทั้งหมดเป็นตัวพิมพ์ใหญ่
แปลงอักขระตัวแรกเป็นตัวพิมพ์เล็ก
แปลงอักขระทั้งหมดเป็นตัวพิมพ์เล็ก
สลับตัวพิมพ์ของอักขระตัวแรก
สลับตัวพิมพ์ของอักขระทั้งหมด
แท็ก: Linux, bash, เชลล์, นิพจน์ทั่วไป, การขยายพารามิเตอร์, RegExp, regex, ความยาว, ออฟเซ็ต, สำหรับ, ใน, ทำ ง่อย, เสร็จแล้ว, *.wav, mp3, CR+LF, นิพจน์ทั่วไป, รูปแบบ, ค้นหา, ตัวแปร, อาเรย์, สตริง, อักขระ, บน, ล่าง, ตัวพิมพ์ใหญ่
5.2 ออฟเซ็ตสำหรับค่าลบ
5.3 ค่าลบ
ค้นหาจำนวนอักขระในไฟล์: $ ARRAY=(`cat file.html`) $ echo $(#ARRAY[@]) 1158
การแนะนำ
คำสั่ง sed คือ Stream EDitor สำหรับการแก้ไขข้อความอัตโนมัติ "ตัวแก้ไขสตรีม" - ในแง่ที่ว่าสามารถแก้ไขสตรีมข้อมูลขาเข้าได้อย่างต่อเนื่อง เช่น เป็นส่วนหนึ่งของช่องทางโปรแกรม (ไปป์) โดยอัตโนมัติ - หมายความว่าทันทีที่คุณตั้งกฎการแก้ไข ส่วนที่เหลือจะเกิดขึ้นโดยที่คุณไม่ต้องมีส่วนร่วมที่น่าเบื่อ กล่าวอีกนัยหนึ่ง เอดิเตอร์ sed ไม่มีการโต้ตอบ
โปรแกรม sed นั้นซับซ้อนกว่าคำสั่งที่เราได้พูดคุยไปแล้วในบทความก่อนหน้าในชุด HuMan มันมีคลังแสงของคำสั่งของตัวเอง ดังนั้นเพื่อหลีกเลี่ยงการพูดซ้ำซากและความสับสน ในบทความนี้ คำสั่ง sed ต่อจากนี้ไปจะเรียกว่า "โปรแกรม" หรือ "ตัวแก้ไข" และคำสั่งของตัวแก้ไข sed จะเรียกง่ายๆ ว่าคำสั่ง
โปรแกรม sed สามารถทำงานที่ซับซ้อนได้ และต้องใช้เวลาในการเรียนรู้วิธีกำหนดงานเหล่านี้
แต่ด้วย. การกระทำที่ซับซ้อนคำสั่ง sed มีคุณสมบัติที่เรียบง่ายแต่มีประโยชน์มาก ซึ่งควบคุมได้ไม่ยากไปกว่าคำสั่ง Unix อื่นๆ อย่าปล่อยให้ตัวเองจมอยู่กับความซับซ้อนของการเรียนรู้โปรแกรมทั้งหมด
เราจะเริ่มจากง่ายไปซับซ้อน เพื่อให้คุณสามารถคิดได้ว่าจะหยุดตรงไหนเสมอ
คำสั่ง s - การทดแทน (การแทนที่)
โปรแกรม sed มีคำสั่งมากมายในตัวมันเอง ผู้ใช้ส่วนใหญ่รู้แค่คำสั่ง s เท่านั้น และนี่ก็เพียงพอแล้วที่จะทำงานกับโปรแกรมแก้ไข sed คำสั่ง s แทนที่ PATTERN ด้วย REPLACE:
sed s/ตัวอย่าง/การเปลี่ยน/
$ สะท้อนวัน | sed s/วัน/คืน/ (ป้อน) คืน
มันไม่ง่ายไปกว่านี้อีกแล้ว และนี่คือตัวอย่างอินพุตจากไฟล์ zar.txt:
ในตอนเช้าเขาออกกำลังกาย
ฟ้าผ่าเป็นประจุไฟฟ้า $ sed s/charge/discharge/ zar.txt ในตอนเช้าเขาออกจากโรงพยาบาลฟ้าผ่าคือการคายประจุไฟฟ้า
ฉันไม่ได้ใส่นิพจน์ s/SAMPLE/REPLACE/ ในเครื่องหมายคำพูดเพราะ
ตัวอย่างนี้
ไม่จำเป็นต้องมีเครื่องหมายคำพูด แต่หากมีอักขระ meta ก็ต้องระบุเครื่องหมายคำพูดด้วย เพื่อไม่ให้หัวของคุณแตกทุกครั้งและไม่ให้ทำผิดพลาดโดยไม่ได้ตั้งใจให้ใส่เครื่องหมายคำพูดเสมอ โดยเฉพาะอย่างยิ่งเครื่องหมายคำพูดที่ "แข็งแกร่งกว่า" นี่เป็นนิสัยที่ดี คุณไม่สามารถทำให้โจ๊กเสียด้วยน้ำมันได้ ฉันก็จะไม่ข้ามเครื่องหมายคำพูดในตัวอย่างที่ตามมาทั้งหมดเช่นกัน
ดังที่เราเห็น คำสั่งทดแทนมีองค์ประกอบสี่ส่วน:
S คำสั่งนั้นเอง /.../.../ ตัวคั่นรูปแบบ PATTERN สำหรับการค้นหาและการแทนที่นิพจน์ REPLACE ที่จะแทนที่ PATTERN หากพบ
เครื่องหมายทับ (/) ถูกใช้เป็นตัวคั่นตามธรรมเนียม เนื่องจากบรรพบุรุษของ sed ซึ่งเป็นเอดิเตอร์ ed ใช้เครื่องหมายเหล่านี้ (เช่นเดียวกับเอดิเตอร์ vi) ในบางกรณี ตัวคั่นดังกล่าวไม่สะดวกอย่างยิ่ง เช่น เมื่อคุณต้องการเปลี่ยนพาธไปยังไดเร็กทอรีที่มีเครื่องหมายทับ (/usr/local/bin) ในกรณีนี้ คุณต้องแยกเครื่องหมายทับไปข้างหน้าด้วยเครื่องหมายแบ็กสแลช:
Sed "s/\/usr\/local\/bin/\/common\/bin/"
สิ่งนี้เรียกว่า "รั้วล้อมรั้ว" และดูน่าเกลียดมากและที่สำคัญที่สุดคือเข้าใจยาก
สิ่งพิเศษเกี่ยวกับ sed คือมันช่วยให้คุณใช้ตัวคั่นใดๆ ได้ เช่น ขีดล่าง:
$ สะท้อนวัน | เซดs_day_night_คืน
หรือลำไส้ใหญ่:
$ สะท้อนวัน | sed s:วัน:คืน:คืน
ขณะค้นหาตัวคั่นที่คุณต้องการ หากได้รับข้อความว่า "incomplete `s command" แสดงว่าอักขระตัวนี้ไม่ใช่ตัวคั่นที่ดี หรือคุณลืมใส่ตัวคั่นหนึ่งหรือสองตัว
ในบทความนี้ ฉันต้องใช้ตัวคั่นแบบเดิม (/) เพื่อหลีกเลี่ยงไม่ให้ผู้อ่านสับสน แต่ถ้าจำเป็น ฉันจะใช้เครื่องหมายตัวหนอน (~) เป็นตัวคั่น
นิพจน์ทั่วไป (RE)(นิพจน์ทั่วไป, regexp, RE)
* เครื่องหมายดอกจันที่ตามหลังสัญลักษณ์หรือนิพจน์ทั่วไปหมายถึงตัวเลขใดๆ (รวมถึงศูนย์) ที่ซ้ำกันของสัญลักษณ์นี้หรือนิพจน์ทั่วไป
\+ ระบุการซ้ำกันของอักขระหรือนิพจน์ทั่วไปหนึ่งรายการหรือมากกว่า
\? หมายถึงไม่มีหรือซ้ำหนึ่งครั้ง
\(ฉัน\)หมายความว่าฉันทำซ้ำอย่างแน่นอน
\(ฉัน,เจ\)จำนวนการทำซ้ำอยู่ในช่วงตั้งแต่ i ถึง j
\(ฉัน,\)จำนวนการซ้ำมากกว่าหรือเท่ากับ i
\(,เจ\) จำนวนการซ้ำน้อยกว่าหรือเท่ากับ j
\(อีกครั้ง\) จำนิพจน์ทั่วไปหรือบางส่วนไว้เพื่อใช้โดยรวมในอนาคต ตัวอย่างเช่น \(a-z\)* จะค้นหาการรวมกันของตัวเลขใดๆ (รวมถึงศูนย์) ตัวอักษรพิมพ์เล็ก
. จับคู่อักขระใดๆ รวมถึงการขึ้นบรรทัดใหม่
^ บ่งชี้นิพจน์ที่เป็นโมฆะที่จุดเริ่มต้นของบรรทัด กล่าวอีกนัยหนึ่ง สิ่งใดก็ตามที่นำหน้าด้วยเครื่องหมายนี้จะต้องปรากฏที่ต้นบรรทัด ตัวอย่างเช่น ^#include จะค้นหาบรรทัดที่ขึ้นต้นด้วย #include
$ เช่นเดียวกับอันก่อนหน้าใช้เฉพาะกับท้ายบรรทัดเท่านั้น
[รายการ]หมายถึงอักขระใดๆ จาก LIST ตัวอย่างเช่น มันจะค้นหาตัวอักษรสระภาษาอังกฤษ
[^รายการ]หมายถึงอักขระใดๆ ยกเว้นที่อยู่ในรายการ ตัวอย่างเช่น [^aeiou] จะค้นหาพยัญชนะใดก็ได้ หมายเหตุ: LIST อาจเป็นช่วงเวลาได้ เช่น [a-z] ซึ่งจะหมายถึงอักษรตัวพิมพ์เล็ก หากคุณต้องการรวม ] (วงเล็บเหลี่ยม) ไว้ใน LIST ให้ระบุก่อนในรายการ หากคุณต้องการรวม - (ยัติภังค์) ในรายการ ให้ระบุเป็นรายการแรกหรือรายการสุดท้าย
RE1\|RE2หมายถึง PB1 หรือ PB2
RE1RE2หมายถึงการรวมนิพจน์ทั่วไป PB1 และ PB2
\nระบุอักขระขึ้นบรรทัดใหม่
\$; \*; \.; \[; \\; \^ หมายความว่าตาม: $; *; .; [; \; ^
ความสนใจ: พักผ่อน สัญลักษณ์ตามแบ็กสแลช (\) ที่นำมาใช้ในภาษา C ไม่ได้รับการสนับสนุนโดยโปรแกรม sed
\1 \2 \3 \4 \5 \6 \7 \8 \9 ระบุส่วนที่ตรงกันของนิพจน์ทั่วไป โดยจัดเก็บโดยใช้เครื่องหมาย \(และ \)
ตัวอย่างบางส่วน:
เอบีซีดีเอฟแปลว่า abcdef
ก*ขแทนศูนย์หรือจำนวนใดๆ ของ a และ b หนึ่งตัว ตัวอย่างเช่น aaaaaaab; ab; หรือข
ก\?ขหมายถึง b หรือ ab
ก\+ข\+แปลว่า หนึ่งหรือ ตัวอักษรเพิ่มเติม a และ b หนึ่งตัวหรือมากกว่า ตัวอย่างเช่น: ab; อ๊าาา; แอ๊บแบ๊บ; หรืออร๊ายยยยย
.* หมายถึงอักขระทุกตัวในบรรทัด ทุกบรรทัด รวมถึงอักขระว่างด้วย
.\+ จับคู่อักขระทั้งหมดบนบรรทัด แต่เฉพาะในบรรทัดที่มีอักขระอย่างน้อยหนึ่งตัวเท่านั้น สตริงว่างไม่ตรงกับนิพจน์ทั่วไปนี้
^main.*(.*)โดยจะค้นหาบรรทัดที่ขึ้นต้นด้วยคำว่า main และมีวงเล็บเปิดและปิดด้วย และอาจมีอักขระกี่ตัวก็ได้ก่อนและหลังวงเล็บเปิด (หรืออาจไม่มีก็ได้)
^# จะค้นหาบรรทัดที่ขึ้นต้นด้วยเครื่องหมาย # (เช่น ความคิดเห็น)
\\$ จะค้นหาบรรทัดที่ลงท้ายด้วยแบ็กสแลช (\)
ตัวอักษรหรือตัวเลขใดๆ
[^ ]\+ (วงเล็บเหลี่ยม นอกเหนือจากสัญลักษณ์ ^ แล้ว ยังมีช่องว่างและแท็บด้วย) -- หมายถึงอักขระหนึ่งตัวหรือจำนวนเท่าใดก็ได้ ยกเว้นช่องว่างและแท็บ โดยปกติแล้วนี่จะหมายถึงคำ
^.*ก.*$วิธี อักษรตัวใหญ่และอยู่ตรงกลางบรรทัดพอดี
อ.\(9\)$ระบุอักษรตัวใหญ่ A ซึ่งเป็นอักษรตัวที่สิบนับจากท้ายบรรทัดพอดี
^.\(,15\)กระบุอักษรตัวใหญ่ A ซึ่งตรงกับตัวที่สิบหกจากจุดเริ่มต้นของบรรทัด
ตอนนี้เราได้เห็นนิพจน์ทั่วไปแล้ว ลองกลับไปที่คำสั่ง s ใน sed กัน
การใช้สัญลักษณ์ & เมื่อไม่ทราบรูปแบบ “ไม่ทราบได้อย่างไร” คุณถามว่า “คุณไม่ทราบว่าคุณต้องการแทนที่อะไร” ฉันจะตอบ: ฉันต้องการใส่ตัวเลขที่พบในข้อความในวงเล็บ วิธีการทำเช่นนี้? คำตอบ: ใช้สัญลักษณ์ &
สัญลักษณ์ & (เครื่องหมายและ) เมื่อวางไว้เป็นส่วนหนึ่งของ REPLACEMENT หมายถึงรูปแบบใดๆ ที่พบในข้อความ ตัวอย่างเช่น:
$ เสียงสะท้อน 1234 | sed "s/*/(&)/" (1234)
จำเป็นต้องใช้เครื่องหมายดอกจัน (เครื่องหมายดอกจัน) หลังช่วงเวลาเพื่อแทนที่ตัวเลขทั้งหมดที่พบในตัวอย่าง หากไม่มีมันก็คงจะเป็น:
$ เสียงสะท้อน 1234 | sed "s//(&)/" (1)234
นั่นคือตัวเลขตัวแรกที่พบนั้นถูกนำมาเป็นตัวอย่าง
นี่คือตัวอย่างที่มีการโหลดที่มีความหมายโดยสมบูรณ์: มาสร้างไฟล์ Formula.txt กัน:
A+432-10=น
และใช้คำสั่งกับมัน:
$ sed "s/*-*/(&)/" Formula.txt a+(432-10)=n
สูตรทางคณิตศาสตร์ได้รับความหมายที่ชัดเจน
สัญลักษณ์เครื่องหมายและอีกตัวหนึ่งสามารถใช้เพื่อเพิ่ม PATTERN เป็นสองเท่า:
$ เสียงสะท้อน 123 | sed "s/*/& &/" 123 123
มีความละเอียดอ่อนอย่างหนึ่งที่นี่ หากเราทำให้ตัวอย่างซับซ้อนขึ้นอีกเล็กน้อย:
$ echo "123 abc" | sed "s/*/& &/" 123 123 abc
อย่างที่คุณคาดหวัง เฉพาะตัวเลขเท่านั้นที่จะเพิ่มเป็นสองเท่าเนื่องจากไม่มีตัวอักษรในรูปแบบ แต่ถ้าเราสลับบางส่วนของข้อความ:
$ echo "abc 123" | sed "s/*/& &/" abc 123
ดังนั้นการคูณตัวเลขจะไม่ได้ผล นี่คือคุณลักษณะของนิพจน์ทั่วไป * - จับคู่เฉพาะอักขระตัวแรกของสตริงเท่านั้น หากเราต้องการเพิ่มเลขสองหลักไม่ว่าจะอยู่ที่ใดก็ตาม เราจำเป็นต้องแก้ไขนิพจน์ทั่วไปใน REPLACE:
$ echo "abc defg 123" | sed "s/*/& &/" abc defg 123 123
จากนั้นตัวเลขจะเพิ่มเป็นสองเท่าโดยไม่คำนึงถึงจำนวน "คำ" ก่อนหน้า
การใช้วงเล็บหลีก \(, \) และ \1 เพื่อประมวลผลส่วนหนึ่งของรูปแบบ วงเล็บหลีก \(และ \) ใช้เพื่อจัดเก็บส่วนหนึ่งของนิพจน์ทั่วไป
สัญลักษณ์ \1 หมายถึงส่วนที่จดจำไว้ส่วนแรก \2 ส่วนที่สอง และอื่นๆ จนถึงเก้าส่วนที่บันทึกไว้ (โปรแกรมไม่รองรับมากกว่านี้) ลองดูตัวอย่าง:
$ echo abcd123 | sed "s/\(*\).*/\1/" abcd
ในที่นี้ \(*\) หมายความว่าโปรแกรมจะต้องจำอักขระตัวอักษรทั้งหมดไม่ว่าจำนวนเท่าใดก็ได้ .* หมายถึงจำนวนอักขระเท่าใดก็ได้หลังจากส่วนแรกที่จำได้ และ \1 หมายความว่าเราต้องการเห็นเพียงส่วนแรกที่จำได้เท่านั้น ถูกต้อง: ในเอาต์พุตของโปรแกรมเราจะเห็นเฉพาะตัวอักษรและไม่มีตัวเลข
ในการสลับคำ คุณต้องจำรูปแบบย่อยสองแบบ แล้วจึงสลับ:
$ echo เพนกวินโง่ |sed "s/\([a-z]*\) \([a-z]*\)/\2 \1/" เพนกวินโง่
โดยที่ \2 หมายถึงรูปแบบย่อยที่สอง และ \1 หมายถึงรูปแบบย่อยแรก สังเกตระยะห่างระหว่างนิพจน์แรก \([a-z]*\) และนิพจน์ที่สอง \([a-z]*\) จำเป็นต้องค้นหาคำสองคำ
เครื่องหมาย \1 ไม่จำเป็นต้องปรากฏเฉพาะใน REPLACEMENT เท่านั้น แต่ยังสามารถปรากฏใน SAMPLE ได้ เช่น เมื่อเราต้องการลบคำที่ซ้ำกัน:
$ echo นกเพนกวิน นกเพนกวิน | sed "s/\([a-z]*\) \1/\1/" เพนกวิน
ตัวดัดแปลงการทดแทนคำสั่ง
ตัวแก้ไขการแทนที่จะถูกวางไว้หลังตัวคั่นสุดท้าย โมดิฟายเออร์เหล่านี้จะกำหนดว่าโปรแกรมจะทำอะไรหากมีการจับคู่ PATTERN ในสตริงมากกว่าหนึ่งรายการ และวิธีการแทนที่
ตัวแก้ไข /g
การทดแทนระดับโลก
โปรแกรม sed เช่นเดียวกับยูทิลิตี้ Unix ส่วนใหญ่ จะอ่านทีละบรรทัดเมื่อทำงานกับไฟล์ ถ้าเราสั่งให้แทนที่คำใด ๆ โปรแกรมจะแทนที่เฉพาะคำแรกที่ตรงกับ PATTERN ในบรรทัดที่กำหนด หากเราต้องการเปลี่ยนทุกคำที่ตรงกับรูปแบบ เราควรป้อนตัวแก้ไข /g
หากไม่มีตัวแก้ไข /g:
$ echo แมวตัวนี้เป็นแมวที่ธรรมดาที่สุด | sed "s/cat/kitten/" ลูกแมวตัวนี้เป็นแมวที่ธรรมดาที่สุด
ผู้แก้ไขจะแทนที่เฉพาะคำแรกที่ตรงกันเท่านั้น
และตอนนี้มีตัวแก้ไขการแทนที่ทั่วโลก:
$ echo แมวตัวนี้เป็นแมวที่ธรรมดาที่สุด | sed "s/cat/kitten/g" ลูกแมวตัวนี้เป็นลูกแมวที่ธรรมดาที่สุด
การแข่งขันทั้งหมดในสตริงนี้ได้ถูกแทนที่แล้ว
และถ้าคุณต้องการเปลี่ยนคำทั้งหมดให้ใส่ในวงเล็บ? จากนั้นสำนวนปกติจะกลับมาช่วยเหลืออีกครั้ง หากต้องการเลือกอักขระตัวอักษรทั้งหมดทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก คุณสามารถใช้โครงสร้าง [A-Ya-Ya] ได้ แต่จะไม่รวมคำเช่น "something" หรือ "s"ezd" โครงสร้าง [^] นั้นมีความหมายมากกว่านั้นมาก สะดวก ]* ซึ่งตรงกับอักขระทั้งหมดยกเว้นช่องว่าง ดังนั้น:
$ สะท้อนนกเพนกวินโง่ ๆ ซ่อนตัวอย่างขี้อาย | sed "s/[^ ]*/(&)/g" (โง่) (เพนกวิน) (ขี้อาย) (ซ่อน)
วิธีการเลือกแมตช์ที่เหมาะสมจากหลาย ๆ อย่าง
หากคุณไม่ใช้ตัวดัดแปลง โปรแกรม sed จะแทนที่เฉพาะคำแรกที่ตรงกับ PATTERN หากคุณใช้โมดิฟายเออร์ /g โปรแกรมจะแทนที่ทุกคำที่ตรงกัน คุณจะเลือกหนึ่งการแข่งขันได้อย่างไรหากมีหลายรายการอยู่ในบรรทัด? - ใช้สัญลักษณ์ที่คุ้นเคยอยู่แล้ว \(และ \) จำตัวอย่างย่อยและเลือกสัญลักษณ์ที่คุณต้องการโดยใช้เครื่องหมาย \1 - \9
$ echo เพนกวินโง่ | sed "s/\([a-z]*\) \([a-z]*\)/\2 /" เพนกวิน
ในตัวอย่างนี้ เราจำทั้งสองคำได้ และหลังจากใส่คำที่สอง (เพนกวิน) ไว้เป็นอันดับแรก เราก็ลบคำแรก (โง่) ออกโดยการเว้นวรรคในส่วน REPLACEMENT ถ้าเราแทนที่ช่องว่างด้วยคำ มันจะแทนที่คำแรก (โง่):
$ echo เพนกวินโง่ | sed "s/\([a-z]*\) \([a-z]*\)/\2 smart /" เพนกวินอัจฉริยะ
ตัวแก้ไขตัวเลข
นี่คือตัวเลขหนึ่ง/สอง/สามหลักที่วางอยู่หลังตัวคั่นสุดท้าย และระบุว่าจะต้องแทนที่คู่ใด
$ echo เพนกวินโง่มาก | sed "s/[a-z]*/good/2" นกเพนกวินที่ดีมาก
ในตัวอย่างนี้ แต่ละคำตรงกัน และเราได้แจ้งให้บรรณาธิการทราบว่าคำใดที่เราต้องการแทนที่ด้วยการวางตัวแก้ไข 2 หลังส่วน REPLACE
คุณสามารถรวมตัวแก้ไขตัวเลขกับตัวแก้ไข /g ได้ หากคุณต้องการปล่อยให้คำแรกไม่เปลี่ยนแปลงและแทนที่คำที่สองและคำถัดไปด้วยคำว่า "(ลบ)" คำสั่งจะเป็นดังนี้:
$ echo เพนกวินโง่มาก | sed "s/[a-z]*/(ลบแล้ว)/2g" มาก (ลบแล้ว) (ลบแล้ว)
หากคุณต้องการลบการจับคู่ที่ตามมาทั้งหมดยกเว้นรายการแรก คุณควรเว้นวรรคในส่วน REPLACE:
$ echo เพนกวินโง่มาก | sed "s/[a-z]*/ /2g" มาก
หรือไม่ใส่อะไรเลย:
$ echo เพนกวินโง่มาก | sed "s/[^ ]*//2g" ดีมาก
ตัวแก้ไขตัวเลขอาจเป็นจำนวนเต็มใดก็ได้ตั้งแต่ 1 ถึง 512 ตัวอย่างเช่น หากคุณต้องการใส่โคลอนหลังอักขระตัวที่ 80 ของแต่ละบรรทัด คำสั่งจะช่วย:
$sed ชื่อไฟล์ "s/./&:/80"
Modifier /p - ส่งออกไปยังเอาต์พุตมาตรฐาน (พิมพ์)
ตามค่าเริ่มต้น โปรแกรม sed จะส่งออกผลลัพธ์ไปยังเอาต์พุตมาตรฐาน (เช่น หน้าจอมอนิเตอร์) ตัวแก้ไขนี้ใช้กับตัวเลือก sed -n เท่านั้น ซึ่งเพิ่งบล็อกเอาต์พุตของผลลัพธ์ไปยังหน้าจอ
ตัวแก้ไข /w
ช่วยให้คุณสามารถบันทึกผลการประมวลผลข้อความได้ ไฟล์ที่ระบุ:
$ sed "s/SAMPLE/REPLACE/w ชื่อไฟล์
/e ตัวแก้ไข (ส่วนขยาย GNU)
อนุญาตให้คุณระบุคำสั่งเชลล์ (ไม่ใช่โปรแกรม sed) เป็นการทดแทน หากพบการจับคู่กับ PATTERN มันจะถูกแทนที่ด้วยเอาต์พุตของคำสั่งที่ระบุในส่วน REPLACE ตัวอย่าง:
$ echo คืน | sed "s/night/echo day/e" วัน
/I และ /i ตัวดัดแปลง (ส่วนขยาย GNU)
ทำให้กระบวนการเปลี่ยนไม่คำนึงถึงขนาดตัวพิมพ์
$ echo ไนท์ | sed "s/คืน/วัน/i" วัน
ชุดค่าผสมตัวแก้ไข
ตัวแก้ไขสามารถนำมารวมกันได้เมื่อเหมาะสม ในกรณีนี้ ควรวางตัวดัดแปลง w ไว้ท้ายสุด
อนุสัญญา (ส่วนขยาย GNU) มีเพียงห้าเท่านั้น:
\ลแปลงอักขระ REPLACE เป็นตัวพิมพ์เล็ก \ลแปลงอักขระ REPLACE ถัดไปเป็นตัวพิมพ์เล็ก \Uแปลงอักขระ REPLACE เป็นตัวพิมพ์ใหญ่ \uแปลงอักขระ REPLACE ถัดไปเป็นตัวพิมพ์ใหญ่ \Eเลิกทำการแปลที่เริ่มโดย \L หรือ \U ด้วยเหตุผลที่ชัดเจน จึงมีการใช้แบบแผนเหล่านี้เพียงอย่างเดียว ตัวอย่างเช่น:
$ echo เพนกวินโง่ | sed "s/stupid/\u&/" นกเพนกวินโง่
$ echo ลูกหมาน้อย | sed "s/[a-z]*/\u&/2" ลูกสุนัขตัวน้อย
เราได้ครอบคลุมเกือบทุกแง่มุมของคำสั่ง sed ถึงเวลาดูตัวเลือกของโปรแกรมนี้แล้ว
ตัวเลือกโปรแกรม sed
โปรแกรมนี้มีตัวเลือกน้อยจนน่าประหลาดใจ (ซึ่งค่อนข้างจะชดเชยส่วนเกินของคำสั่ง, ตัวดัดแปลง และฟังก์ชันอื่นๆ) นอกจากตัวเลือกที่รู้จักกันดี --help (-h) และ --version (-V) ซึ่งเราจะไม่พิจารณาแล้ว มีเพียงสามตัวเลือกเท่านั้น:
ตัวเลือก -e--expression=command_set
วิธีหนึ่งในการดำเนินการหลายคำสั่งคือการใช้ตัวเลือก -e ตัวอย่างเช่น:
Sed -e "s/a/A/" -e "s/b/B/" ชื่อไฟล์
ตัวอย่างก่อนหน้านี้ทั้งหมดในบทความนี้ไม่จำเป็นต้องใช้ตัวเลือก -e เพียงเพราะมีคำสั่งเดียว เราสามารถใช้ตัวเลือก -e ในตัวอย่างได้ ซึ่งจะไม่เปลี่ยนแปลงอะไรเลย
ตัวเลือก -ฉหากคุณต้องการดำเนินการคำสั่งจำนวนมาก จะสะดวกกว่าถ้าเขียนคำสั่งลงในไฟล์และใช้ตัวเลือก -f:
Sed -f ชื่อไฟล์ sedscript
Sedscript นี่คือชื่อของไฟล์ที่มีคำสั่ง ไฟล์นี้เรียกว่าสคริปต์โปรแกรม sed (ต่อไปนี้จะเรียกว่าสคริปต์) แต่ละคำสั่งสคริปต์ควรใช้บรรทัดแยกกัน ตัวอย่างเช่น:
# ความคิดเห็น - สคริปต์นี้จะเปลี่ยนสระตัวพิมพ์เล็กทั้งหมดเป็นสระตัวพิมพ์ใหญ่ s/a/A/g s/e/E/g s/i/I/g s/o/O/g s/u/U/g
คุณสามารถตั้งชื่อสคริปต์ตามที่คุณต้องการได้ สิ่งสำคัญคือต้องไม่สับสนระหว่างไฟล์สคริปต์กับไฟล์ที่กำลังประมวลผล
ตัวเลือก -nโปรแกรม sed -n ไม่พิมพ์สิ่งใดไปยังเอาต์พุตมาตรฐาน หากต้องการรับการถอนเงิน คุณต้องมีคำแนะนำพิเศษ เราคุ้นเคยกับโมดิฟายเออร์ /p เรียบร้อยแล้ว ซึ่งสามารถใช้เพื่อบ่งชี้ดังกล่าวได้ จำไฟล์ zar.txt กัน:
$ sed "s/1-9/&/p" zar.txt ในตอนเช้าเขาออกกำลังกาย
ฟ้าผ่าเป็นประจุไฟฟ้า
เนื่องจากไม่พบรายการที่ตรงกันกับ PATTERN (ไม่มีตัวเลขในไฟล์) คำสั่ง s พร้อมด้วยโมดิฟายเออร์ /p และเครื่องหมาย & เป็นการแทนที่ (โปรดจำไว้ว่าเครื่องหมายแอมเพอร์แซนด์หมายถึง PATTERN นั่นเอง) จึงทำงานเหมือนกับคำสั่ง cat
หากพบ PATTERN ในไฟล์ บรรทัดที่มี PATTERN จะเพิ่มเป็นสองเท่า:
$ sed "s/exercise/&/p" zar.txt ในตอนเช้าเขาออกกำลังกาย
ในตอนเช้าเขาออกกำลังกาย
ฟ้าผ่าเป็นประจุไฟฟ้า
ตอนนี้เรามาเพิ่มตัวเลือก -n:
$ sed -n "s/exercise/&/p" zar.txt ในตอนเช้าเขาออกกำลังกาย
- ตอนนี้โปรแกรมของเราทำงานเหมือนกับคำสั่ง grep - มันจะส่งคืนเฉพาะบรรทัดที่มี PATTERN เท่านั้น
- การเลือกองค์ประกอบที่ต้องการของข้อความที่แก้ไข
- ด้วยการใช้คำสั่งเดียว เราได้เห็นความสามารถอันน่าทึ่งของโปรแกรมแก้ไข sed แต่ทุกสิ่งที่เขาทำก็ลงมาเพื่อค้นหาและแทนที่ นอกจากนี้ ในระหว่างการดำเนินการ sed จะแก้ไขแต่ละบรรทัดทีละบรรทัดโดยไม่ต้องสนใจบรรทัดอื่นๆ จะสะดวกกว่าหากจำกัดแถวที่ต้องเปลี่ยน เช่น
- เลือกบรรทัดตามตัวเลข
- เลือกแถวในช่วงตัวเลขที่กำหนด
- เลือกเฉพาะแถวที่มีนิพจน์บางอย่าง
เลือกเฉพาะบรรทัดระหว่างบางนิพจน์
เลือกเฉพาะบรรทัดตั้งแต่ต้นไฟล์จนถึงนิพจน์บางส่วน
เลือกเฉพาะบรรทัดจากนิพจน์บางส่วนจนถึงจุดสิ้นสุดของไฟล์
โปรแกรม sed ทำทั้งหมดนี้และอีกมากมาย คำสั่ง sed editor ใดๆ สามารถใช้ตามแอดเดรส ในช่วงของแอดเดรสที่กำหนด หรือภายใต้ข้อจำกัดข้างต้นในช่วงของบรรทัด ที่อยู่หรือข้อจำกัดจะต้องนำหน้าคำสั่งทันที:
Sed "ที่อยู่/คำสั่งจำกัด"
การเลือกแถวตามตัวเลข
นี่เป็นกรณีที่ง่ายที่สุด เพียงระบุจำนวนบรรทัดที่ต้องการก่อนคำสั่ง:
$ sed "4 s/[a-z]*//i" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาดในยามพลบค่ำในยามเช้า ในหิมะที่ละลายในฤดูใบไม้ผลิ ให้กับทุกสิ่งที่พินาศและชาญฉลาด
$ sed "2.3 s/В/(В)/" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาด (ใน) สนธยายามเช้าตรู่ (ใน) หิมะที่ละลายในฤดูใบไม้ผลิ ในทุกสิ่งที่พินาศและฉลาด
หากคุณต้องการระบุช่วงจนถึงบรรทัดสุดท้ายของไฟล์ แต่คุณไม่รู้ว่ามีกี่บรรทัด ให้ใช้เครื่องหมาย $:
$ sed "2,$ s/в/(в)/i" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาด (ใน) ยามพลบค่ำยามเช้า (ใน) การละลายของหิมะในฤดูใบไม้ผลิ (ใน) ทุกสิ่งที่พินาศและเป็นอยู่ ฉลาด.
การเลือกแถวที่มีนิพจน์
นิพจน์การค้นหาจะอยู่ในเครื่องหมายทับ (/) และวางไว้หน้าคำสั่ง:
$ sed "/morning/ s/in/(in)/i" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาด (ใน) ยามพลบค่ำยามเช้า ในหิมะที่ละลายในฤดูใบไม้ผลิ ในทุกสิ่งที่พินาศและฉลาด
การเลือกแถวในช่วงระหว่างสองนิพจน์
เช่นเดียวกับในกรณีของหมายเลขบรรทัด ช่วงจะถูกระบุโดยคั่นด้วยเครื่องหมายจุลภาค:
$ sed "/morning/,/wise/ s/in/(in)/i" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาด (ใน) สนธยายามเช้าตรู่ (ใน) หิมะละลายในฤดูใบไม้ผลิ (ใน) ทุกอย่าง ที่พินาศและฉลาด
การเลือกบรรทัดจากจุดเริ่มต้นของไฟล์ไปจนถึงนิพจน์ที่ต้องการ
$ sed "1,/snow/ s/in/(in)/i" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาด (ใน) ยามพลบค่ำยามเช้า (ใน) การละลายของหิมะในฤดูใบไม้ผลิ ในทุกสิ่งที่พินาศและเป็น ฉลาด.
การเลือกบรรทัดจากนิพจน์หนึ่งไปยังส่วนท้ายของไฟล์
$ sed "/snow/,$ s/in/(in)/i" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาดในยามพลบค่ำยามเช้า (ใน) หิมะที่ละลายในฤดูใบไม้ผลิ (ใน) ทุกสิ่งที่พินาศและเป็นอยู่ ฉลาด.
คำสั่ง sed editor อื่นๆ
คำสั่ง d (ลบ)
ลบบรรทัดต่อไปนี้ออกจากเอาต์พุตมาตรฐาน:
$ sed "2 d" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาดในหิมะที่ละลายในฤดูใบไม้ผลิในทุกสิ่งที่พินาศและฉลาด
และบ่อยครั้งที่พวกเขาเขียนให้ง่ายขึ้น (ไม่มีช่องว่าง):
Sed "2d" กูมิเลฟ.txt
ทุกสิ่งที่กล่าวไว้ในส่วนที่แล้วเกี่ยวกับการกำหนดแอดเดรสสตริงยังใช้กับคำสั่ง d ด้วย (เช่นเดียวกับคำสั่งเกือบทั้งหมดในตัวแก้ไข sed)
การใช้คำสั่ง d จะสะดวกในการทิ้ง "ส่วนหัว" ที่ไม่จำเป็นของข้อความเมลบางส่วน:
$sed ชื่อไฟล์ "1,/^$/d"
(ลบบรรทัดตั้งแต่บรรทัดแรกถึงบรรทัดว่างบรรทัดแรก)
กำจัดความคิดเห็นในไฟล์กำหนดค่า:
$ sed "/^#/d" /boot/grub/menu.lst
และคุณไม่มีทางรู้ว่าจะต้องลบบรรทัดพิเศษตรงไหน!
คำสั่ง p (พิมพ์)
คำภาษาอังกฤษ "print" แปลว่า "print" ซึ่งในภาษารัสเซียมีความเกี่ยวข้องกับเครื่องพิมพ์หรืออย่างน้อยก็ด้วยแป้นพิมพ์ อันที่จริง คำนี้ในบริบทภาษาอังกฤษมักหมายถึงการส่งออกไปยังหน้าจอมอนิเตอร์ ดังนั้นคำสั่ง p จะไม่พิมพ์อะไรเลย แต่เพียงแสดงบรรทัดที่ระบุ
เมื่อใช้โดยตัวมันเอง คำสั่ง p จะเพิ่มบรรทัดในเอาต์พุตเป็นสองเท่า (ท้ายที่สุดแล้ว โปรแกรม sed จะพิมพ์บรรทัดไปที่หน้าจอตามค่าดีฟอลต์ และคำสั่ง p จะพิมพ์บรรทัดเดียวกันเป็นครั้งที่สอง)
$ echo ฉันมีแมว | sed "p" ฉันมีแมว ฉันมีแมว
มีการใช้คุณสมบัตินี้ เช่น เพิ่มบรรทัดว่างเป็นสองเท่าเพื่อปรับปรุงรูปลักษณ์ของข้อความ:
$ sed "/^$/ p ชื่อไฟล์
แต่คำสั่ง p จะแสดงสีที่แท้จริงเมื่อใช้ร่วมกับตัวเลือก -n ซึ่งตามที่คุณจำได้ จะป้องกันไม่ให้มีเส้นพิมพ์บนหน้าจอ ด้วยการรวมตัวเลือก -n เข้ากับคำสั่ง p คุณจะได้รับเฉพาะบรรทัดที่ต้องการในเอาต์พุต
ตัวอย่างเช่น ดูที่บรรทัดที่หนึ่งถึงสิบ:
$ sed -n ชื่อไฟล์ "1.10 p"
หรือเพียงแค่แสดงความคิดเห็น:
$ sed -n "/^#/ p" /boot/grub/menu.lst # ไฟล์การกำหนดค่า GRUB "/boot/grub/menu.lst"
# สร้างโดย "grubconfig" อาทิตย์ 23 มี.ค. 2551 เวลา 21:45:41 น. # # เริ่มส่วนส่วนกลางของ GRUB # สิ้นสุดส่วนส่วนกลางของ GRUB # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Linux เริ่มต้นขึ้น # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Linux สิ้นสุดลง # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Linux เริ่มต้นขึ้น # การกำหนดค่าพาร์ติชันที่บูตได้ของ Linux สิ้นสุด
สิ่งนี้ชวนให้นึกถึงโปรแกรม grep มาก ซึ่งเราพบแล้วเมื่อเราพูดถึงตัวเลือก -n พร้อมกับโมดิฟายเออร์ /p แต่แตกต่างจากคำสั่ง grep ตัวแก้ไข sed ช่วยให้ไม่เพียงค้นหาบรรทัดเหล่านี้เท่านั้น แต่ยังสามารถเปลี่ยนบรรทัดเหล่านั้นได้ เช่น แทนที่ Linux ทุกที่ด้วย Unix:
$ sed -n "/^#/ p" /boot/grub/menu.lst | sed "s/Linux/Unix/" # ไฟล์การกำหนดค่า GRUB "/boot/grub/menu.lst"
# สร้างโดย "grubconfig" อาทิตย์ 23 มี.ค. 2551 เวลา 21:45:41 น. # # เริ่มส่วนส่วนกลางของ GRUB # สิ้นสุดส่วนส่วนกลางของ GRUB # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Unix เริ่มต้นขึ้น # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Unix สิ้นสุดลง # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Unix เริ่มต้นขึ้น # การกำหนดค่าพาร์ติชันที่สามารถบูตได้ของ Unix สิ้นสุดลง ทีม!บางครั้งคุณจำเป็นต้องแก้ไขแถวทั้งหมด ยกเว้นแถวที่ตรงกับรูปแบบหรือส่วนที่เลือก เครื่องหมาย
เครื่องหมายอัศเจรีย์
(!) สลับการเลือก ตัวอย่างเช่น ลองลบบรรทัดทั้งหมดยกเว้นบรรทัดที่สองจาก quatrain ของ Gumilyov:
$ sed "2 !d" gumilev.txt ในยามพลบค่ำยามเช้า
หรือเลือกทุกบรรทัด ยกเว้นความคิดเห็น จากไฟล์ /boot/grub/menu.lst:
$ sed -n "/^#/ !p" /boot/grub/menu.lst ค่าเริ่มต้น 1 หมดเวลา 20 gfxmenu (hd0,3)/boot/message title SuSe บนเคอร์เนล root (/dev/hda3) (hd0,2) /boot/vmlinuz root=/dev/hda3 ro vga=773 acpi=off title Linux บน (/dev/hda4) root (hd0,3) เคอร์เนล /boot/vmlinuz root=/dev/hda4 ro vga=0x317
$sed ชื่อไฟล์ "11 q"
คำสั่งนี้จะเสร็จสิ้นเมื่อถึงบรรทัดที่ 11
คำสั่ง q เป็นหนึ่งในคำสั่ง sed ไม่กี่คำสั่งที่ไม่ยอมรับช่วงสตริง คำสั่งไม่สามารถหยุดทำงาน 10 ครั้งติดต่อกันได้หากเราป้อน:
Sed "1.10 q" ไร้สาระ!
คำสั่ง w (เขียน)
เช่นเดียวกับโมดิฟายเออร์ w ของคำสั่ง s คำสั่งนี้อนุญาตให้คุณเขียนเอาต์พุตของโปรแกรมลงในไฟล์:
$ sed -n "3,$ w gum.txt" กูมิเลฟ.txt
เราจะได้รับไฟล์ gum.txt ที่มี quatrain ของ Gumilyov สองบรรทัดสุดท้ายจากไฟล์ gumilev.txt ยิ่งไปกว่านั้น หากไฟล์ดังกล่าวมีอยู่แล้ว ไฟล์นั้นจะถูกเขียนทับ หากคุณไม่ป้อนตัวเลือก -n โปรแกรมจะแสดงเนื้อหาทั้งหมดของไฟล์ gumilev.txt นอกเหนือจากการสร้างไฟล์ gum.txt แล้ว
สำหรับการทำงานบนบรรทัดคำสั่ง จะสะดวกกว่าถ้าใช้การเปลี่ยนเส้นทางเอาต์พุตปกติ (> หรือ >>) แต่ในสคริปต์ sed คำสั่ง w อาจจะพบการใช้งานของมัน
คำสั่ง r (อ่าน)
คำสั่งนี้ไม่เพียงแต่อ่านไฟล์ที่ระบุเท่านั้น แต่ยังวางเนื้อหาลงในตำแหน่งที่ต้องการในไฟล์ที่แก้ไขด้วย ในการเลือก "สถานที่ที่เหมาะสม" จะใช้ที่อยู่ที่เราคุ้นเคยอยู่แล้ว (ตามหมายเลขบรรทัดตามสำนวน ฯลฯ ) ตัวอย่าง:
$ echo จากบทกวีของ Gumilyov: | sed "r gumilev.txt"
จากบทกวีของ Gumilyov:
ช่างเป็นความสุขอันน่าประหลาดอย่างยิ่งในเวลาพลบค่ำในยามเช้า ในหิมะที่ละลายในฤดูใบไม้ผลิ ในทุกสิ่งที่พินาศและฉลาด
ทีม=
จะให้หมายเลขบรรทัดที่ระบุ:
$ sed "/snow/=" gumilev.txt ช่างเป็นความสุขที่แปลกประหลาดในยามพลบค่ำยามเช้า 3 ในหิมะที่ละลายในฤดูใบไม้ผลิในทุกสิ่งที่พินาศและฉลาด
$ sed -n "/snow/=" gumilev.txt 3
คำสั่งยอมรับที่อยู่เดียวเท่านั้น ไม่ยอมรับช่วงเวลา
คำสั่งย
คำสั่งนี้จะแทนที่อักขระจากส่วน PATTERN ด้วยอักขระจากส่วน REPLACE ซึ่งทำงานเหมือนกับโปรแกรม ตร.
$ echo Car - มรดกแห่งอดีต | sed "y/Auto/Paro/" รถจักรไอน้ำ - มรดกจากอดีต
ทีม ยใช้งานได้เฉพาะเมื่อจำนวนอักขระในรูปแบบเท่ากับจำนวนอักขระใน REPLACEMENT
สคริปต์โปรแกรม sed
เพื่อที่จะใช้ sed editor เป็นตัวแก้ไขอย่างเต็มรูปแบบ โปรแกรมแก้ไขข้อความคุณต้องเชี่ยวชาญการเขียน sed scripts โปรแกรม sed มีภาษาโปรแกรมที่เรียบง่ายของตัวเอง ซึ่งช่วยให้คุณสามารถเขียนสคริปต์ที่สามารถทำงานได้อย่างมหัศจรรย์
บทความนี้ไม่สามารถมีคำอธิบายของสคริปต์ sed ได้ เช่นเดียวกับที่ผู้เขียนไม่ได้กำหนดหน้าที่ของตัวเองในการเรียนรู้ภาษาการเขียนโปรแกรม sed ในบทความนี้ ฉันมุ่งเน้นไปที่การใช้โปรแกรมแก้ไข sed บนบรรทัดคำสั่ง โดยคำนึงถึงการใช้มันเป็นตัวกรองในไปป์ ด้วยเหตุนี้ ฉันจึงละเว้นคำสั่ง sed จำนวนมากที่ใช้ในสคริปต์ sed เท่านั้น
มีแฟน ๆ ของบรรณาธิการ sed มากมายและมีบทความมากมายเกี่ยวกับหัวข้อการเขียนสคริปต์รวมถึงบน RuNet ดังนั้นสำหรับผู้ที่สนใจโปรแกรมที่ยอดเยี่ยมนี้ การขยายความรู้จึงไม่ใช่เรื่องยาก
โปรแกรม sed และอักขระซีริลลิก
ดังที่เห็นได้จากตัวอย่างในบทความนี้ โปรแกรม sed บนระบบ Russified ที่เหมาะสมนั้นใช้ภาษาที่ "ยอดเยี่ยมและทรงพลัง" ได้อย่างคล่องแคล่ว
สรุปโปรแกรม sed
โปรแกรม sed เป็นตัวแก้ไขโฟลว์ข้อมูลแบบมัลติฟังก์ชั่น ซึ่งขาดไม่ได้สำหรับ:
- การแก้ไขอาร์เรย์ข้อความขนาดใหญ่
- การแก้ไขไฟล์ทุกขนาดเมื่อลำดับการแก้ไขซับซ้อนเกินไป
- การแก้ไขข้อมูลตามที่มี รวมถึงแบบเรียลไทม์ นั่นคือในกรณีที่การใช้โปรแกรมแก้ไขข้อความเชิงโต้ตอบเป็นเรื่องยากหรือเป็นไปไม่ได้เลย
หากต้องการเชี่ยวชาญโปรแกรม sed อย่างเต็มรูปแบบ จะต้องใช้เวลาหลายสัปดาห์หรือหลายเดือน เนื่องจากต้องใช้:
- เรียนรู้นิพจน์ทั่วไป
- เรียนรู้การเขียนสคริปต์ sed โดยการเรียนรู้ภาษาโปรแกรมง่ายๆ ที่ใช้ในสคริปต์เหล่านี้
ในทางกลับกัน การเรียนรู้คำสั่งต่างๆ ที่พบบ่อยที่สุดใน sed editor นั้นไม่ยากไปกว่าคำสั่ง Unix ใดๆ ฉันหวังว่าบทความนี้จะช่วยคุณในเรื่องนี้
คำหลัง
จนถึงขณะนี้ ในบทความของซีรีส์ HuMan ฉันได้พยายามเปิดเผยแต่ละตัวเลือกโดยย่อ แต่ละพารามิเตอร์ของคำสั่งที่อธิบายไว้ อย่างน้อยที่สุดเพื่อให้บทความสามารถแทนที่มานาได้ ต่อไปผมจะยึดหลักนี้ต่อไป
บทความนี้เป็นข้อยกเว้น เนื่องจากไม่ได้อธิบายคุณลักษณะทั้งหมดของโปรแกรม คำอธิบายที่สมบูรณ์ไม่จำเป็นต้องมีบทความ แต่เป็นหนังสือ อย่างไรก็ตามบทความนี้ช่วยให้คุณเข้าใจแนวคิดเกี่ยวกับโปรแกรมแก้ไข sed และเริ่มต้นใช้งานโปรแกรมที่น่าทึ่งนี้โดยใช้คำสั่งทั่วไป