Trình chỉnh sửa luồng - Biểu thức chính quy

Chính các biểu thức chính quy làm cho SED trở nên mạnh mẽ và hiệu quả. Một số tác vụ phức tạp có thể được giải quyết bằng biểu thức chính quy. Bất kỳ chuyên gia dòng lệnh nào cũng biết sức mạnh của các biểu thức chính quy.

Giống như nhiều tiện ích GNU / Linux khác, SED cũng hỗ trợ các biểu thức chính quy, thường được gọi là regex. Chương này mô tả chi tiết các biểu thức chính quy. Chương này được chia thành ba phần: Biểu thức chính quy chuẩn, các lớp POSIX của biểu thức chính quy và ký tự Meta.

Biểu thức chính quy tiêu chuẩn

Đầu dòng (^)

Trong thuật ngữ biểu thức chính quy, biểu tượng dấu mũ (^) khớp với đầu dòng. Ví dụ sau in tất cả các dòng bắt đầu bằng mẫu "The".

[jerry]$ sed -n '/^The/ p' books.txt

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

The Two Towers, J. R. R. Tolkien 
The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
The Pilgrimage, Paulo Coelho

Cuối dòng ($)

Cuối dòng được biểu thị bằng ký hiệu đô la ($). Ví dụ sau in các dòng kết thúc bằng "Coelho".

[jerry]$ sed -n '/Coelho$/ p' books.txt

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

The Alchemist, Paulo Coelho 
The Pilgrimage, Paulo Coelho

Ký tự đơn (.)

Dấu chấm (.) Khớp với bất kỳ ký tự đơn nào ngoại trừ ký tự cuối dòng. Ví dụ sau đây in ra tất cả ba từ ký tự kết thúc bằng ký tự "t".

[jerry]$ echo -e "cat\nbat\nrat\nmat\nbatting\nrats\nmats" | sed -n '/^..t$/p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

cat 
bat 
rat 
mat

Bộ ký tự khớp ([])

Trong thuật ngữ biểu thức chính quy, một tập ký tự được biểu diễn bằng dấu ngoặc vuông ([]). Nó chỉ được sử dụng để khớp một trong số một số ký tự. Ví dụ sau phù hợp với các mẫu "Gọi" và "Cao" nhưng không khớp với "Bóng".

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[CT]all/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Call 
Tall

Bộ độc quyền ([^])

Trong tập hợp độc quyền, dấu mũ phủ định tập hợp các ký tự trong dấu ngoặc vuông. Ví dụ sau chỉ in "Ball".

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[^CT]all/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Ball

Phạm vi ký tự ([-])

Khi một phạm vi ký tự được cung cấp, biểu thức chính quy khớp với bất kỳ ký tự nào trong phạm vi được chỉ định trong dấu ngoặc vuông. Ví dụ sau phù hợp với "Call" và "Tall" nhưng không khớp với "Ball".

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[C-Z]all/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Call 
Tall

Bây giờ chúng ta hãy sửa đổi phạm vi thành "AP" và quan sát kết quả.

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[A-P]all/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Call 
Ball

Không có một lần xuất hiện (\?)

Trong SED, dấu chấm hỏi (\?) Khớp với 0 hoặc một lần xuất hiện của ký tự đứng trước. Ví dụ sau phù hợp với "Behavior" cũng như "Behavior". Ở đây, chúng tôi đã đặt "u" làm ký tự tùy chọn bằng cách sử dụng "\?".

[jerry]$ echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Behaviour 
Behavior

Một hoặc nhiều lần xuất hiện (\ +)

Trong SED, biểu tượng dấu cộng (\ +) khớp với một hoặc nhiều lần xuất hiện của ký tự đứng trước. Ví dụ sau phù hợp với một hoặc nhiều lần xuất hiện của "2".

[jerry]$ echo -e "111\n22\n123\n234\n456\n222"  | sed -n '/2\+/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

22 
123 
234 
222

Không có hoặc nhiều lần xuất hiện (*)

Dấu hoa thị (*) khớp với số lần xuất hiện không hoặc nhiều hơn của ký tự đứng trước. Ví dụ sau phù hợp với "ca", "cat", "catt", v.v.

[jerry]$ echo -e "ca\ncat" | sed -n '/cat*/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

ca 
cat

Chính xác N lần xuất hiện {n}

{n} đối sánh chính xác "n" lần xuất hiện của ký tự đứng trước. Ví dụ sau chỉ in các số có ba chữ số. Nhưng trước đó, bạn cần tạo tệp sau chỉ chứa các số.

[jerry]$ cat numbers.txt

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

1 
10 
100 
1000 
10000 
100000 
1000000 
10000000 
100000000 
1000000000

Hãy để chúng tôi viết biểu thức SED.

[jerry]$ sed -n '/^[0-9]\{3\}$/ p' numbers.txt

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

100

Lưu ý rằng cặp dấu ngoặc nhọn được thoát bởi ký tự "\".

Ít nhất n lần xuất hiện {n,}

{n,} khớp với ít nhất "n" lần xuất hiện của ký tự đứng trước. Ví dụ sau đây in ra tất cả các số lớn hơn hoặc bằng năm chữ số.

[jerry]$ sed -n '/^[0-9]\{5,\}$/ p' numbers.txt

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

10000 
100000 
1000000
10000000 
100000000 
1000000000

M đến N Sự xuất hiện {m, n}

{m, n} khớp với ít nhất "m" và nhiều nhất "n" lần xuất hiện của ký tự đứng trước. Ví dụ sau in tất cả các số có ít nhất năm chữ số nhưng không nhiều hơn tám chữ số.

[jerry]$ sed -n '/^[0-9]\{5,8\}$/ p' numbers.txt

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

10000 
100000 
1000000 
10000000

Ống (|)

Trong SED, ký tự ống dẫn hoạt động giống như phép toán HOẶC logic. Nó khớp với các mục từ hai bên của đường ống. Ví dụ sau phù hợp với "str1" hoặc "str3".

[jerry]$ echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

str1 
str3

Lưu ý rằng cặp dấu ngoặc đơn và dấu gạch ngang (|) được thoát ra bởi ký tự "\".

Nhân vật đang chạy trốn

Có một số ký tự đặc biệt. Ví dụ: dòng mới được biểu thị bằng "\ n", dấu xuống dòng được biểu thị bằng "\ r", v.v. Để sử dụng các ký tự này vào ngữ cảnh ASCII thông thường, chúng ta phải thoát chúng bằng cách sử dụng ký tự gạch chéo ngược (\). Chương này minh họa việc thoát các ký tự đặc biệt.

Đang thoát "\"

Ví dụ sau phù hợp với mẫu "\".

[jerry]$ echo 'str1\str2' | sed -n '/\\/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

str1\str2

Đang thoát "\ n"

Ví dụ sau phù hợp với ký tự dòng mới.

[jerry]$ echo 'str1\nstr2' | sed -n '/\\n/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

str1\nstr2

Đang thoát "\ r"

Ví dụ sau phù hợp với ký tự xuống dòng.

[jerry]$ echo 'str1\rstr2' | sed -n '/\\r/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

str1\rstr2

Đang thoát "\ dnnn"

Điều này khớp với một ký tự có giá trị ASCII thập phân là "nnn". Ví dụ sau chỉ khớp với ký tự "a".

[jerry]$ echo -e "a\nb\nc" | sed -n '/\d97/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

a

Đang thoát "\ onnn"

Điều này khớp với một ký tự có giá trị ASCII bát phân là "nnn". Ví dụ sau chỉ khớp với ký tự "b".

[jerry]$ echo -e "a\nb\nc" | sed -n '/\o142/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

b

Điều này khớp với một ký tự có giá trị ASCII thập lục phân là "nnn". Ví dụ sau chỉ khớp với ký tự "c".

[jerry]$ echo -e "a\nb\nc" | sed -n '/\x63/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

c

Các loại biểu thức chính quy POSIX

Có một số từ dành riêng có ý nghĩa đặc biệt. Các từ dành riêng này được gọi là các lớp POSIX của biểu thức chính quy. Phần này mô tả các lớp POSIX được hỗ trợ bởi SED.

[: alnum:]

Nó bao hàm các ký tự chữ cái và số. Ví dụ sau chỉ khớp với "Một" và "123", nhưng không khớp với ký tự tab.

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alnum:]]/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

One 
123

[: alpha:]

Nó chỉ bao hàm các ký tự trong bảng chữ cái. Ví dụ sau chỉ phù hợp với từ "Một".

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alpha:]]/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

One

[:chỗ trống:]

Nó ngụ ý ký tự trống có thể là dấu cách hoặc tab. Ví dụ sau chỉ khớp với ký tự tab.

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:space:]]/ p' | cat -vte

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

^I$

Lưu ý rằng lệnh "cat -vte" được sử dụng để hiển thị các ký tự tab (^ I).

[: chữ số:]

Nó chỉ ngụ ý số thập phân. Ví dụ sau chỉ khớp với chữ số "123".

[jerry]$ echo -e "abc\n123\n\t" | sed -n '/[[:digit:]]/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

123

[:thấp hơn:]

Nó chỉ ngụ ý các chữ cái thường. Ví dụ sau chỉ khớp với "một".

[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:lower:]]/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

one

[:phía trên:]

Nó chỉ bao hàm các chữ cái viết hoa. Ví dụ sau chỉ khớp với "TWO".

[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:upper:]]/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

TWO

[: câu:]

Nó ngụ ý các dấu câu bao gồm các ký tự không phải dấu cách hoặc chữ và số

[jerry]$ echo -e "One,Two\nThree\nFour" | sed -n '/[[:punct:]]/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

One,Two

[:không gian:]

Nó ngụ ý các ký tự khoảng trắng. Ví dụ sau đây minh họa điều này.

[jerry]$ echo -e "One\n123\f\t" | sed -n '/[[:space:]]/ p' | cat -vte

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

123^L^I$

Metacharacters

Giống như biểu thức chính quy truyền thống, SED cũng hỗ trợ siêu ký tự. Đây là các biểu thức chính quy kiểu Perl. Lưu ý rằng hỗ trợ siêu ký tự là GNU SED cụ thể và có thể không hoạt động với các biến thể khác của SED. Hãy để chúng tôi thảo luận chi tiết về siêu ký tự.

Ranh giới từ (\ b)

Trong thuật ngữ cụm từ thông dụng, "\ b" khớp với ranh giới từ. Ví dụ: "\ bthe \ b" khớp với "the" nhưng không khớp với "these", "there", "them", "then", v.v. Ví dụ sau đây minh họa điều này.

[jerry]$ echo -e "these\nthe\nthey\nthen" | sed -n '/\bthe\b/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

the

Ranh giới Không từ (\ B)

Trong thuật ngữ cụm từ thông dụng, "\ B" khớp với ranh giới không phải từ. Ví dụ: "the \ B" đối sánh với "this" và "they" nhưng không khớp với "the". Ví dụ sau đây minh họa điều này.

[jerry]$ echo -e "these\nthe\nthey" | sed -n '/the\B/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

these 
they

Khoảng trắng đơn (\ s)

Trong SED, "\ s" ngụ ý một ký tự khoảng trắng. Ví dụ sau phù hợp với "Dòng \ t1" nhưng không khớp với "Dòng1".

[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\s/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Line 1

Không có khoảng trắng duy nhất (\ S)

Trong SED, "\ S" ngụ ý một ký tự khoảng trắng. Ví dụ sau phù hợp với "Line2" nhưng không khớp với "Line \ t1".

[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\S/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

Line2

Ký tự một từ (\ w)

Trong SED, "\ w" ngụ ý ký tự từ đơn, tức là ký tự chữ cái, chữ số và dấu gạch dưới (_). Ví dụ sau đây minh họa điều này.

[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\w/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

One 
123 
1_2

Một ký tự không phải từ (\ W)

Trong SED, "\ W" ngụ ý một ký tự không phải từ, hoàn toàn trái ngược với "\ w". Ví dụ sau đây minh họa điều này.

[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\W/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

&;#

Bắt đầu không gian mẫu (\ `)

Trong SED, "\` "ngụ ý phần đầu của không gian mẫu. Ví dụ sau chỉ phù hợp với từ "Một".

[jerry]$ echo -e "One\nTwo One" | sed -n '/\`One/ p'

Khi thực thi đoạn mã trên, bạn nhận được kết quả sau:

One