Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม Bash

การทดแทน Sed ขั้นสูง:เทคนิคจากผู้เชี่ยวชาญและตัวอย่างการปฏิบัติ

การทดแทน Sed ขั้นสูง:เทคนิคจากผู้เชี่ยวชาญและตัวอย่างการปฏิบัติ บทความนี้เป็นส่วนหนึ่งของชุดเคล็ดลับและเทคนิค Unix Sed ที่ดำเนินอยู่

ในบทความ sed ก่อนหน้านี้ เราได้เรียนรู้ — การพิมพ์ sed, การลบ sed, sed แทน, การเขียนไฟล์ sed และคำสั่งหลายคำสั่ง sed

ในบทความนี้ เราจะมาทบทวนวิธีแก้ปัญหาที่น่าสนใจด้วยคำสั่งทดแทน “s” ใน sed พร้อมตัวอย่างที่เป็นประโยชน์มากมาย

ฉัน. ตัวคั่นการทดแทน Sed

ดังที่เราได้พูดคุยกันในโพสต์ที่แล้ว เราสามารถใช้ตัวคั่นที่แตกต่างกันได้ เช่น @ % |; :ในคำสั่ง sed ทดแทน

ก่อนอื่นให้เราสร้างไฟล์ path.txt ที่จะใช้ในตัวอย่างทั้งหมดที่กล่าวถึงด้านล่างนี้

$ cat path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

ตัวอย่างที่ 1 – sed @ ตัวคั่น:แทนที่ /opt/omni/lbin เป็น /opt/tools/bin

เมื่อคุณเปลี่ยนชื่อเส้นทางที่มี '/' คุณสามารถใช้ @ เป็นตัวคั่นแทน '/' ในตัวอย่าง sed ด้านล่าง ในบรรทัดสุดท้ายของไฟล์อินพุต /opt/omni/lbin ถูกเปลี่ยนเป็น /opt/tools/bin

$ sed 's@/opt/omni/lbin@/opt/tools/bin@g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/tools/bin:/opt/omni/sbin:/root/bin

ตัวอย่างที่ 2 – sed / ตัวคั่น:แทนที่ /opt/omni/lbin เป็น /opt/tools/bin

เมื่อคุณควรใช้ '/' ในการทดแทนที่เกี่ยวข้องกับชื่อเส้นทาง คุณจะต้องหลีกเลี่ยง '/' ในข้อมูลการทดแทนดังที่แสดงด้านล่าง ในตัวอย่าง sed นี้ ตัวคั่น '/' จะถูกหลีกหนีในส่วน REGEXP และ REPLACEMENT

$ sed 's/\/opt\/omni\/lbin/\/opt\/tools\/bin/g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/tools/bin:/opt/omni/sbin:/root/bin

ครั้งที่สอง Sed '&' รับสตริงที่ตรงกัน

ส่วนที่แม่นยำของบรรทัดอินพุตซึ่งการจับคู่นิพจน์ทั่วไปจะแสดงด้วย &ซึ่งจากนั้นสามารถนำมาใช้ในส่วนทดแทนได้

ตัวอย่างที่ 1 – sed &การใช้งาน:แทนที่ /usr/bin/ เป็น /usr/bin/local

$ sed 's@/usr/bin@&/local@g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin/local:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin/local:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

ในตัวอย่างข้างต้น '&' ในส่วนทดแทนจะแทนที่ด้วย /usr/bin ซึ่งเป็นรูปแบบที่ตรงกัน และเพิ่มด้วย /local ดังนั้นในผลลัพธ์ที่เกิดขึ้นทั้งหมด /usr/bin จะถูกแทนที่ด้วย /usr/bin/local

ตัวอย่างที่ 2 – sed &การใช้งาน:จับคู่ทั้งบรรทัด

&แทนที่รายการที่ตรงกันด้วย REGEXP ที่กำหนด

$ sed 's@^.*$@<<<&>>>@g' path.txt
<<</usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin>>>
<<</usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:>>>
<<</opt/omni/lbin:/opt/omni/sbin:/root/bin>>>

ในตัวอย่างข้างต้น regexp มี “^.*$” ซึ่งตรงกับทั้งบรรทัด ส่วนทดแทน <<<&>>> เขียนทั้งบรรทัดโดยมี <<<และ>>> อยู่ที่จุดเริ่มต้นและจุดสิ้นสุดของบรรทัดตามลำดับ

III. การจัดกลุ่มและการอ้างอิงกลับใน Sed

การจัดกลุ่มสามารถใช้ใน sed ได้เหมือนกับนิพจน์ทั่วไปทั่วไป กลุ่มถูกเปิดด้วย “\(” และปิดด้วย “\)” การจัดกลุ่มสามารถใช้ร่วมกับการอ้างอิงกลับได้

การอ้างอิงด้านหลังคือการนำส่วนหนึ่งของนิพจน์ทั่วไปที่เลือกโดยการจัดกลุ่มกลับมาใช้ใหม่ การอ้างอิงย้อนกลับใน sed สามารถใช้ได้ทั้งในนิพจน์ทั่วไปและในส่วนแทนที่ของคำสั่งทดแทน

ตัวอย่างที่ 1:รับเฉพาะเส้นทางแรกในแต่ละบรรทัด

$ sed 's/\(\/[^:]*\).*/\1/g' path.txt
/usr/kbos/bin
/usr/local/sbin
/opt/omni/lbin

ในตัวอย่างข้างต้น \(\/[^:]*\) จับคู่เส้นทางที่มีอยู่ก่อน first :มา \1 แทนที่กลุ่มแรกที่ตรงกัน

ตัวอย่างที่ 2:การจัดกลุ่มหลายกลุ่ม

ในไฟล์ path.txt ให้เปลี่ยนลำดับของฟิลด์ในบรรทัดสุดท้ายของไฟล์

$ sed '$s@\([^:]*\):\([^:]*\):\([^:]*\)@\3:\2:\1@g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/omni/bin:
/root/bin:/opt/omni/sbin:/opt/omni/lbin

ในคำสั่งข้างต้น $ ระบุการทดแทนที่จะเกิดขึ้นเฉพาะสำหรับบรรทัดสุดท้าย เอาต์พุตแสดงให้เห็นว่าลำดับของค่าพาธในบรรทัดสุดท้ายกลับรายการแล้ว

ตัวอย่างที่ 3:รับรายการชื่อผู้ใช้ในไฟล์ /etc/passwd

ตัวอย่าง sed นี้แสดงเฉพาะฟิลด์แรกจากไฟล์ /etc/passwd

$sed 's/\([^:]*\).*/\1/' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown

ตัวอย่างที่ 4:วงเล็บอักขระตัวแรกของแต่ละคำ

ตัวอย่าง sed นี้พิมพ์อักขระตัวแรกของทุกคำในวงเล็บ

$ echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g'
(W)elcome (T)o (T)he (G)eek (S)tuff

ตัวอย่างที่ 5:กำหนดจำนวนอย่างง่าย

ให้เราสร้างไฟล์ชื่อตัวเลขซึ่งมีรายการตัวเลข ตัวอย่างคำสั่ง sed ด้านล่างใช้เพื่อยืนยันตัวเลขจนถึงหลักพัน

$ cat numbers
1234
12121
3434
123
$sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers
1,234
12,121
3,434
123