ตัวแก้ไขสตรีม - นิพจน์ทั่วไป

เป็นนิพจน์ทั่วไปที่ทำให้ 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