+2

Một vài lưu ý khi sử dụng Shell Script (phần 4)

Phần trước: Một vài lưu ý khi sử dụng Shell Script (phần 3)

IV. sed là quá đủ

sed là một text editor thường được cài sẵn trong máy của bạn và có thể giúp bạn tăng hiệu suất làm việc lên cao hơn. sed giúp giải quyết những tasks nhàm chán một cách đơn giản hơn, mà bạn cũng không cần tốn quá nhiều thời gian để học những cơ bản về sed.

sed là một stream editor

sed là một non-interactive editor. Điều đó có nghĩa là, không giống như những text editors khác mà bạn đã sử dụng như vim hay sublime, nó chỉ đọc một tập hợp lệnh từ một script, sau đó sẽ thực thi những lệnh đó với file cung cấp.

Ví dụ:

$ sed -e 'script commands here' file.txt

Đó là cách để chạy inline command với sed. Chúng ta cũng có thể thay flag -e thành -f để truyền filename vào câu lệnh sử dụng sed.

$ sed -f scriptfile file.txt

Các bạn nên đọc thêm manpage của sed để biết thêm về các arguments mà sed sử dụng.

Cấu trúc câu lệnh sed

Một câu lệnh sed bao gồm một address và một editing instruction.

  • address chỉ ra những dòng mà sed sẽ thực thi câu lệnh
  • editing instruction giúp sed biết phải làm gì với những dòng đó

Address

Một address có thể là một line number, một regular expression, hay một ký tự đặc biệt, ví dụ như $ là dòng cuối cùng, hay \n là ký tự chuyển dòng.

Trong câu lệnh sed không bắt buộc phải có address. Khi không có address thì sed sẽ thực thi câu lệnh ở tất cả các dòng của file. Bạn có thể cung cấp một hoặc hai address. Trong trường hợp một address được chỉ thị, câu lệnh sẽ được thực thi ở những dòng thích hợp với address đó. Trong trường hợp hai address được chỉ thị, câu lệnh sẽ được thực thi cho những dòng nằm giữa hai vị trí đó. Các vị trí được phân tách nhau bằng dấu ,

Ví dụ:

$ sed -e '1,3 command' file.txt
# câu lệnh sẽ thực thi ở dòng 1, 2 và 3 của file

$ sed -e '/PATTERN/ command' file.txt
# câu lệnh sẽ thực thi ở những dòng phù hợp với pattern ở trên

$ sed -e '/BEGIN/,/END/ command' file.txt
# câu lệnh sẽ thực thi từ dòng thích hợp với BEGIN đến dòng thích hợp với END

Editing instruction

instruction là những ký tự đơn chỉ cho sed biết phải làm gì với dòng hiện tại. instruction hay được dùng nhất là s, để thay đổi nội dung theo pattern.

Ví dụ:

$ echo 'foo bar foo baz' | sed -e 's/foo/FOO/'
# FOO bar foo baz

Câu lệnh trên cũng có thể nhận thêm argument (hoặc flag), ví dụ khi muốn thay thế tất cả các đoạn trong câu tương ứng với pattern, chứ ko chỉ thay thế mỗi đoạn đầu tiên, thì ta có thể đưa thêm flag g vào.

$ echo 'foo bar foo baz' | sed -e 's/foo/FOO/g'
# FOO bar FOO baz

Nếu bạn muốn thực thi nhiều hơn một câu lệnh với một address, hãy đặt chúng trong dấu ngoặc {}:

$ sed -e '/bar/{
s/a/A/g
a\
this line was appended
}' file.txt

Câu lệnh trên sẽ đọc file read.txt, với mỗi dòng thoả mãn pattern /bar/ thì sẽ thay thế a bằng A, sau đó sẽ tạo thêm dòng mới với nội dung "this line was appended". Bạn cũng có thể thực hiện những xử lý khác nhau với các addresses khác nhau, trong cùng một script:

$ sed -e '/bar/{
s/a/A/g
a\
this line was appended
}
/foo/d' file.txt

Câu lệnh trên xử lý giống câu lệnh trước đó, cộng thêm việc sẽ delete các dòng thoả mãn pattern /foo/.

Một vài chú ý

Nếu các bạn để ý, chắc sẽ nhận ra sed không thay đổi file gốc mà chỉ hiển thị kết quả của việc thực thi script. Giống như hầu hết các chương trình UNIX khác, sed nhận input và đưa kết quả để standard output.

Vậy phải làm thế nào để có thể thay đổi file với script của bạn?

Chúng ta có thể sử dụng argument -i để giúp sed tạo ra một backup file chứa nội dung của file trước khi script được thực thi.

Ví dụ:

$ sed -i '.bkp' -e '/foo/d' file.txt

Câu lệnh trên sẽ thực thi script (xoá tất cả các dòng thoả mãn pattern /foo/) và tạo ra một file backup là file.txt.bkp, với nội dung của file.txt lúc đầu.

Nếu bạn đã tự tin với đoạn script của mình, chỉ cần truyền string rỗng vào là sed sẽ thay thế luôn file gốc.

$ sed -i'' -e '/foo/d' file.txt
# file.txt bị thay đổi, không có backup file được tạo

sed hoạt động tốt hơn với những người bạn 😃

Người bạn tốt nhất của sed có lẽ là find. Đây là câu lệnh dùng để tìm kiếm một cái gì đó trong filesystem của bạn.

Cứ ví dụ như bạn đã phạm một sai lầm tồi tệ như ghi password của một vài users ra log file. Giờ bạn cần phải sửa sai bằng cách tìm và xoá toàn bộ những dòng chứa chữ "password" trong hàng tá những log files. Nếu bạn biết đến sed, thì rất đơn giản:

$ find . -name "*.log" -exec sed -i'' -e '/password/d' {} \;

find sẽ tìm tất cả các log file và thực thi câu lệnh sed, {} có nghĩa là "thêm những file bạn tìm thấy vào đây", không có gì khác biệt với những ví dụ mà chúng ta đã nhắc đến bên trên.

Kết luận

sed là một tool rất mạnh, giúp chúng ta tiết kiệm rất nhiều thời gian chỉ với vài câu lệnh đơn giản. Nếu bạn muốn xem thêm những điều mà sed có thể làm, hãy thử check file này nhé.


Source: Enough sed to be useful


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí