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