ตัวแก้ไขสตรีม - นิพจน์ทั่วไป
เป็นนิพจน์ทั่วไปที่ทำให้ SED มีประสิทธิภาพและประสิทธิผล งานที่ซับซ้อนจำนวนมากสามารถแก้ไขได้ด้วยนิพจน์ทั่วไป ผู้เชี่ยวชาญด้านบรรทัดคำสั่งรู้ถึงพลังของนิพจน์ทั่วไป
เช่นเดียวกับยูทิลิตี้ GNU / Linux อื่น ๆ SED ก็รองรับนิพจน์ทั่วไปเช่นกันซึ่งมักเรียกกันว่า regex. บทนี้อธิบายนิพจน์ทั่วไปโดยละเอียด บทนี้แบ่งออกเป็นสามส่วน: นิพจน์ทั่วไปมาตรฐานคลาส POSIX ของนิพจน์ทั่วไปและอักขระเมตา
นิพจน์ทั่วไปมาตรฐาน
จุดเริ่มต้นของบรรทัด (^)
ในคำศัพท์ของนิพจน์ทั่วไปสัญลักษณ์คาเร็ต (^) จะจับคู่จุดเริ่มต้นของบรรทัด ตัวอย่างต่อไปนี้จะพิมพ์เส้นทั้งหมดที่ขึ้นต้นด้วยรูปแบบ "The"
[jerry]$ sed -n '/^The/ p' books.txt
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
The Two Towers, J. R. R. Tolkien
The Alchemist, Paulo Coelho
The Fellowship of the Ring, J. R. R. Tolkien
The Pilgrimage, Paulo Coelho
ท้ายบรรทัด ($)
จุดสิ้นสุดของบรรทัดแสดงด้วยสัญลักษณ์ดอลลาร์ ($) ตัวอย่างต่อไปนี้จะพิมพ์บรรทัดที่ลงท้ายด้วย "Coelho"
[jerry]$ sed -n '/Coelho$/ p' books.txt
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
The Alchemist, Paulo Coelho
The Pilgrimage, Paulo Coelho
อักขระเดี่ยว (.)
จุด (.) จับคู่อักขระเดี่ยวใด ๆ ยกเว้นอักขระท้ายบรรทัด ตัวอย่างต่อไปนี้จะพิมพ์คำตัวอักษรทั้งสามที่ลงท้ายด้วยอักขระ "t"
[jerry]$ echo -e "cat\nbat\nrat\nmat\nbatting\nrats\nmats" | sed -n '/^..t$/p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
cat
bat
rat
mat
จับคู่ชุดอักขระ ([])
ในคำศัพท์นิพจน์ทั่วไปชุดอักขระจะแสดงด้วยวงเล็บเหลี่ยม ([]) ใช้เพื่อจับคู่อักขระเพียงตัวเดียวจากหลายตัว ตัวอย่างต่อไปนี้ตรงกับรูปแบบ "Call" และ "Tall" แต่ไม่ใช่ "Ball"
[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[CT]all/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Call
Tall
ชุดพิเศษ ([^])
ในชุดพิเศษเครื่องหมายคาเร็ตจะลบล้างชุดอักขระในวงเล็บเหลี่ยม ตัวอย่างต่อไปนี้จะพิมพ์เฉพาะ "Ball"
[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[^CT]all/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Ball
ช่วงอักขระ ([-])
เมื่อระบุช่วงอักขระนิพจน์ทั่วไปจะจับคู่อักขระใด ๆ ภายในช่วงที่ระบุในวงเล็บเหลี่ยม ตัวอย่างต่อไปนี้ตรงกับ "Call" และ "Tall" แต่ไม่ใช่ "Ball"
[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[C-Z]all/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Call
Tall
ตอนนี้ให้เราแก้ไขช่วงเป็น "AP" และสังเกตผลลัพธ์
[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[A-P]all/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Call
Ball
Zero on One Occurrence (\?)
ใน SED เครื่องหมายคำถาม (\?) จะจับคู่ค่าศูนย์หรือหนึ่งครั้งของอักขระนำหน้า ตัวอย่างต่อไปนี้ตรงกับ "Behavior" และ "Behavior" ที่นี่เราสร้าง "u" เป็นอักขระเสริมโดยใช้ "\?"
[jerry]$ echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Behaviour
Behavior
เหตุการณ์อย่างน้อยหนึ่งครั้ง (\ +)
ใน SED สัญลักษณ์บวก (\ +) จะจับคู่อักขระที่อยู่ก่อนหน้าอย่างน้อยหนึ่งครั้ง ตัวอย่างต่อไปนี้ตรงกับเหตุการณ์ "2" อย่างน้อยหนึ่งครั้ง
[jerry]$ echo -e "111\n22\n123\n234\n456\n222" | sed -n '/2\+/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
22
123
234
222
การเกิดขึ้นเป็นศูนย์หรือมากกว่า (*)
เครื่องหมายดอกจัน (*) จะจับคู่อักขระที่อยู่ข้างหน้าเป็นศูนย์หรือมากกว่า ตัวอย่างต่อไปนี้ตรงกับ "ca", "cat", "catt" และอื่น ๆ
[jerry]$ echo -e "ca\ncat" | sed -n '/cat*/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
ca
cat
N ครั้งเดียว {n}
{n} ตรงทุกประการกับ "n" ที่เกิดขึ้นของอักขระนำหน้า ตัวอย่างต่อไปนี้จะพิมพ์ตัวเลขสามหลักเท่านั้น แต่ก่อนหน้านั้นคุณต้องสร้างไฟล์ต่อไปนี้ซึ่งมีเฉพาะตัวเลขเท่านั้น
[jerry]$ cat numbers.txt
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
1
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000
ให้เราเขียนนิพจน์ SED
[jerry]$ sed -n '/^[0-9]\{3\}$/ p' numbers.txt
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
100
โปรดทราบว่าวงเล็บปีกกาทั้งคู่จะหลีกหนีโดยอักขระ "\"
อย่างน้อย n ครั้ง {n,}
{n,} ตรงกับรายการที่เกิดขึ้นอย่างน้อย "n" ของอักขระนำหน้า ตัวอย่างต่อไปนี้จะพิมพ์ตัวเลขทั้งหมดที่มากกว่าหรือเท่ากับห้าหลัก
[jerry]$ sed -n '/^[0-9]\{5,\}$/ p' numbers.txt
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
10000
100000
1000000
10000000
100000000
1000000000
การเกิด M ถึง N {m, n}
{m, n} ตรงกับ "m" เป็นอย่างน้อยและมากที่สุด "n" ที่เกิดขึ้นของอักขระนำหน้า ตัวอย่างต่อไปนี้จะพิมพ์ตัวเลขทั้งหมดที่มีอย่างน้อยห้าหลัก แต่ไม่เกินแปดหลัก
[jerry]$ sed -n '/^[0-9]\{5,8\}$/ p' numbers.txt
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
10000
100000
1000000
10000000
ท่อ (|)
ใน SED อักขระไปป์จะทำงานเหมือนตรรกะหรือการดำเนินการ จับคู่รายการจากด้านใดด้านหนึ่งของท่อ ตัวอย่างต่อไปนี้ตรงกับ "str1" หรือ "str3"
[jerry]$ echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
str1
str3
โปรดสังเกตว่าคู่ของวงเล็บและไปป์ (|) จะถูกหลีกเลี่ยงโดยอักขระ "\"
อักขระที่หลบหนี
มีอักขระพิเศษบางอย่าง ตัวอย่างเช่นขึ้นบรรทัดใหม่แสดงด้วย "\ n" การกลับรถจะแสดงด้วย "\ r" และอื่น ๆ ในการใช้อักขระเหล่านี้ในบริบท ASCII ปกติเราต้องหลีกเลี่ยงโดยใช้อักขระ backward slash (\) บทนี้แสดงให้เห็นถึงการหลบหนีของอักขระพิเศษ
กำลังหนี "\"
ตัวอย่างต่อไปนี้ตรงกับรูปแบบ "\"
[jerry]$ echo 'str1\str2' | sed -n '/\\/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
str1\str2
กำลังหนี "\ n"
ตัวอย่างต่อไปนี้ตรงกับอักขระบรรทัดใหม่
[jerry]$ echo 'str1\nstr2' | sed -n '/\\n/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
str1\nstr2
กำลังหนี "\ r"
ตัวอย่างต่อไปนี้ตรงกับการคืนแคร่
[jerry]$ echo 'str1\rstr2' | sed -n '/\\r/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
str1\rstr2
กำลังหนี "\ dnnn"
ตรงกับอักขระที่มีค่า ASCII ทศนิยมคือ "nnn" ตัวอย่างต่อไปนี้จับคู่เฉพาะอักขระ "a"
[jerry]$ echo -e "a\nb\nc" | sed -n '/\d97/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
a
กำลังหนี "\ onnn"
ตรงกับอักขระที่มีค่า ASCII ฐานแปดคือ "nnn" ตัวอย่างต่อไปนี้จับคู่เฉพาะอักขระ "b"
[jerry]$ echo -e "a\nb\nc" | sed -n '/\o142/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
b
ตรงกับอักขระที่มีค่า ASCII เลขฐานสิบหกคือ "nnn" ตัวอย่างต่อไปนี้จับคู่เฉพาะอักขระ "c"
[jerry]$ echo -e "a\nb\nc" | sed -n '/\x63/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
c
POSIX คลาสของนิพจน์ทั่วไป
มีคำสงวนบางคำที่มีความหมายพิเศษ คำสงวนเหล่านี้เรียกว่าคลาส POSIX ของนิพจน์ทั่วไป ส่วนนี้อธิบายถึงคลาส POSIX ที่ SED สนับสนุน
[: alnum:]
หมายถึงอักขระตามตัวอักษรและตัวเลข ตัวอย่างต่อไปนี้จับคู่เฉพาะ "หนึ่ง" และ "123" แต่ไม่ตรงกับอักขระแท็บ
[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alnum:]]/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
One
123
[: alpha:]
หมายถึงอักขระตามตัวอักษรเท่านั้น ตัวอย่างต่อไปนี้จับคู่คำว่า "หนึ่ง" เท่านั้น
[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alpha:]]/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
One
[: ว่าง:]
หมายถึงอักขระว่างซึ่งอาจเป็นช่องว่างหรือแท็บก็ได้ ตัวอย่างต่อไปนี้จับคู่เฉพาะอักขระแท็บ
[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:space:]]/ p' | cat -vte
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
^I$
โปรดทราบว่าคำสั่ง "cat -vte" ใช้เพื่อแสดงอักขระแท็บ (^ I)
[: หลัก:]
หมายถึงตัวเลขทศนิยมเท่านั้น ตัวอย่างต่อไปนี้จับคู่กับตัวเลข "123" เท่านั้น
[jerry]$ echo -e "abc\n123\n\t" | sed -n '/[[:digit:]]/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
123
[: ต่ำกว่า:]
หมายถึงอักษรตัวพิมพ์เล็กเท่านั้น ตัวอย่างต่อไปนี้ตรงกับ "หนึ่ง" เท่านั้น
[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:lower:]]/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
one
[: บน:]
หมายถึงอักษรตัวพิมพ์ใหญ่เท่านั้น ตัวอย่างต่อไปนี้ตรงเฉพาะ "TWO"
[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:upper:]]/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
TWO
[: วรรค:]
หมายถึงเครื่องหมายวรรคตอนซึ่งรวมถึงอักขระที่ไม่ใช่ช่องว่างหรือตัวเลขและตัวอักษร
[jerry]$ echo -e "One,Two\nThree\nFour" | sed -n '/[[:punct:]]/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
One,Two
[: ช่องว่าง:]
หมายถึงอักขระเว้นวรรค ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
[jerry]$ echo -e "One\n123\f\t" | sed -n '/[[:space:]]/ p' | cat -vte
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
123^L^I$
Metacharacters
เช่นเดียวกับนิพจน์ทั่วไปทั่วไป SED ยังรองรับอักขระเมตาคาแร็กเตอร์ นี่คือนิพจน์ทั่วไปสไตล์ Perl โปรดทราบว่าการรองรับ metacharacter เป็นแบบเฉพาะของ GNU SED และอาจใช้กับ SED รุ่นอื่นไม่ได้ ให้เราพูดคุยเกี่ยวกับ metacharacters โดยละเอียด
ขอบเขตคำ (\ b)
ในคำศัพท์นิพจน์ทั่วไป "\ b" จะตรงกับขอบเขตของคำ ตัวอย่างเช่น "\ bthe \ b" จับคู่ "the" แต่ไม่ใช่ "these", "there", "they", "then" และอื่น ๆ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
[jerry]$ echo -e "these\nthe\nthey\nthen" | sed -n '/\bthe\b/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
the
ขอบเขตที่ไม่ใช่คำ (\ B)
ในคำศัพท์นิพจน์ทั่วไป "\ B" จะจับคู่ขอบเขตที่ไม่ใช่คำ ตัวอย่างเช่น "the \ B" จะจับคู่ "สิ่งเหล่านี้" และ "พวกเขา" แต่ไม่ใช่ "the" ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
[jerry]$ echo -e "these\nthe\nthey" | sed -n '/the\B/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
these
they
ช่องว่างเดียว
ใน SED "\ s" แสดงถึงอักขระช่องว่างเดียว ตัวอย่างต่อไปนี้ตรงกับ "Line \ t1" แต่ไม่ตรงกับ "Line1"
[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\s/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Line 1
ช่องว่างเดียว (\ S)
ใน SED "\ S" หมายถึงอักขระช่องว่างเดียว ตัวอย่างต่อไปนี้ตรงกับ "Line2" แต่ไม่ตรงกับ "Line \ t1"
[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\S/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
Line2
อักขระคำเดียว (\ w)
ใน SED "\ w" หมายถึงอักขระคำเดี่ยว ได้แก่ อักขระตามตัวอักษรตัวเลขและขีดล่าง (_) ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\w/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
One
123
1_2
อักขระที่ไม่ใช่คำเดียว (\ W)
ใน SED "\ W" หมายถึงอักขระที่ไม่ใช่คำเดี่ยวซึ่งตรงข้ามกับ "\ w" ทุกประการ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\W/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
&;#
จุดเริ่มต้นของ Pattern Space (\ `)
ใน SED "\` "หมายถึงจุดเริ่มต้นของพื้นที่รูปแบบ ตัวอย่างต่อไปนี้จับคู่คำว่า "หนึ่ง" เท่านั้น
[jerry]$ echo -e "One\nTwo One" | sed -n '/\`One/ p'
ในการรันโค้ดด้านบนคุณจะได้ผลลัพธ์ดังต่อไปนี้:
One