Một vài lưu ý khi sử dụng Shell Script (phần 4)
Bài đăng này đã không được cập nhật trong 8 năm
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ệnhediting 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