Lệnh sed trong Linux
Sed tượng trưng cho stream editor. Nó là 1 công cụ rất hữu ích cho việc xử lý văn bản, và là 1 tiện ích tuyệt vời để làm việc với các biểu thức chính quy. Việc sử dụng phổ biến nhất của sed là thay thế văn bản. Trong bài viết này, chúng ta sẽ cùng tìm hiểu qua các kỹ thuật được sử dụng thường xuyên nhất với lệnh sed trong Linux.
1. Cú pháp chính
sed có thể được dùng để thay thế những xuất hiện của 1 chuỗi với 1 chuỗi khác trong 1 văn bản.
$ sed 's/pattern/replace_string/' file
hoặc
$ cat file | sed 's/pattern/replace_string/'
Trong đó pattern có thể là chuỗi ký tự hoặc 1 biểu thức chính quy. Trong 1 văn bản, chuỗi cần thay thế (pattern) có thể xuất hiện từ 0 đến nhiều lần, mỗi lần như vậy được gọi là 1 xuất hiện của chuỗi cần thay thế.
Nếu chúng ta sử dụng trình biên tập vim, chúng ta sẽ để ý thấy rằng lệnh dùng để thay thế văn bản trong vim rất giống với cú pháp của sed.
2. Lưu các thay đổi vào tập tin
Mặc định, sed chỉ in ra các văn bản được thay thế. Để lưu các thay đổi này vào cùng 1 tập tin, sử dụng tùy chọn -i. Phần lớn người dùng thực hiện nhiều chuyển hướng để lưu tập tin sau khi thực hiện thay đổi như sau:
$ sed 's/text/replace/' file > newfile
$ mv newfile file
Tuy nhiên, chúng ta chỉ cần 1 lệnh sau để thực hiện việc trên:
$ sed -i 's/text/replace/' file
3. Thay thế tất cả xuất hiện của mẫu
Nếu chúng ta sử dụng các cú pháp đã đề cập ở trên, sed sẽ thay thế sự xuất hiện đầu tiên của mẫu (pattern) trong mỗi dòng. Nếu chúng ta muốn thay thế tất cả xuất hiện của mẫu trong văn bản, chúng ta cần thêm tham số g vào cuối như sau:
$ sed 's/pattern/replace_string/g' file
Hậu tố /g có nghĩa là nó sẽ thay thế các xuất hiện của mẫu cho đến cuối văn bản, mặc định nó sẽ bắt đầu với xuất hiện thứ 1 của mẫu.
Tuy nhiên, đôi khi chúng ta không muốn thay thế tất cả xuất hiện của mẫu, mà chỉ muốn thay thế từ xuất hiện thứ N của mẫu cho đến cuối văn bản. Để làm việc này, chúng ta có thể sử dụng dạng /Ngnhư sau:
Ví dụ:
$ echo thisthisthisthis | sed 's/this/THIS/2g'
thisTHISTHISTHIS
$ echo thisthisthisthis | sed 's/this/THIS/3g'
thisthisTHISTHIS
$ echo thisthisthisthis | sed 's/this/THIS/4g'
thisthisthisTHIS
Nếu chúng ta chỉ muốn thay thế xuất hiện thứ N của mẫu trong văn bản, sử dụng dạng /N như sau:
$ echo thisthisthisthis | sed 's/this/THIS/2'
thisTHISthisthis
$ echo thisthisthisthis | sed 's/this/THIS/3'
thisthisTHISthis
$ echo thisthisthisthis | sed 's/this/THIS/4'
thisthisthisTHIS
4. Ký tự dấu phân cách
Trong các ví dụ trên, chúng ta đã sử dụng / làm ký tự dấu phân cách của sed. Chúng ta có thể sử dụng các ký tự phân cách bất kỳ như sau:
$ sed 's:text:replace:g'
$ sed 's|text|replace|g'
Khi 1 ký tự phân cách xuất hiện bên trong mẫu, chúng ta phải thoát nó bằng việc sử dụng tiền tố \, như sau:
$ sed 's|te\|xt|replace|g'
5. Xóa các dòng trống
Xóa các dòng trống là 1 kỹ thuật đơn giản với việc sử dụng sed. Các khoảng trống có thể được đối chiếu với biểu thức chính quy ^$:
$ sed '/^$/d' file
/pattern/d sẽ xóa các dòng trùng khớp với pattern.
Với các dòng trống, ký hiệu kết thúc dòng xuất hiện kế bên ký hiệu bắt đầu dòng.
6. Xóa các dòng chứa 1 chuỗi bất kỳ
Để xóa các dòng có chứa 1 chuỗi bất kỳ nào đó, ta sử dụng như sau:
Ví dụ: giả sử ta muốn xóa các dòng chứa chuỗi "mobile phones" trong tập tin sentence.txt
$ sed 's/ [^.]*mobile phones[^.]*\.//g' sentence.txt
7. Ký hiệu chuỗi trùng khớp (&)
Trong sed, chúng ta có thể sử dụng & như 1 chuỗi trùng khớp cho các mẫu thay thế, theo cách này, chúng ta có thể sử dụng chuỗi trùng khớp này trong chuỗi thay thế.
Ví dụ:
$ echo this is an example | sed 's/\w\+/[&]/g'
[this] [is] [an] [example]
Ở đây, biểu thức chính quy \w\+ đối chiếu tất cả các từ trong văn bản. Sau đó, chúng ta thay thế nó với [&], & tương ứng với từ trùng khớp.
8. Ký hiệu đối chiếu chuỗi con (\1)
& tương ứng với chuỗi trùng khớp cho mẫu được cho. Chúng ta cũng có thể đối chiếu các chuỗi con của mẫu được cho.
$ echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
this is 7 in a number
Lệnh trên thay thế digit 7 với 7. Chuỗi con trùng khớp là 7. \(pattern\) được dùng để đối chiếu chuỗi con. Mẫu này được bao đóng trong (), và được thoát với \. Với chuỗi con đầu tiên trùng khớp, ký hiệu tương ứng là \1; với chuỗi con thứ 2, ký hiệu là \2, và cứ thế.
Cùng
$ echo seven EIGHT | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
EIGHT seven
\([a-z]\+\) khớp với từ đầu tiên, và \([A-Z]\+\) khớp với từ thứ 2. \1 và \2 được dùng cho việc tham chiếu đến chúng. Trong phần thay thế, thứ tự của chúng được đổi thành \2 \1 và, do vậy, nó xuất hiện với thứ tự ngược lại.
9. Kết hợp nhiều biểu thức
Thông thường để kết hợp nhiều lệnh sed với nhau, chúng ta thường sử dụng toán tử pipe (|) như sau:
$ sed 'expression' | sed 'expression'
Lệnh trên tương đương với:
$ sed 'expression; expression'
hoặc
$ sed -e 'expression' -e 'expression'
Ví dụ:
$ echo abc | sed 's/a/A/' | sed 's/c/C/'
AbC
$ echo abc | sed 's/a/A/;s/c/C/'
AbC
$ echo abc | sed -e 's/a/A/' -e 's/c/C/'
AbC
10. Trích dẫn
Thông thường, các biểu thức của sed được trích dẫn bởi dấu ngoặc đơn ". Nhưng dấu ngoặc kép "" cũng có thể dùng được. Dấu ngoặc kép mở rộng biểu thức bằng việc đánh giá chúng. Sử dụng ngoặc kép hữu dụng khi chúng ta muốn sử dụng 1 biến trong 1 biểu thức của sed.
Ví dụ:
$ text=hello
$ echo hello world | sed "s/$text/HELLO/"
HELLO world
Chúng ta kết thúc bài tìm hiểu về lệnh sed trong Linux tại đây. Chúc các bạn thành công!
Nhận xét
Đăng nhận xét