บทความนี้เป็นส่วนหนึ่งของชุดเคล็ดลับและเทคนิค 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