Linux: 3 lệnh quan trọng để xử lý dữ liệu text
Để làm việc với dữ liệu text, có lẽ nhiều người đã từng sử dụng grep
, sed
, hay awk
. Tuy nhiên, việc thành thạo những lệnh này cũng không đơn giản. Trong bài viết này, tôi sẽ trình bày những hiểu biết của mình về các sử dụng 3 lệnh trên. Nếu vẫn còn loay hoay với những lệnh này thì đây là bài viết dành cho bạn. (Còn thành thạo rồi thì thôi :D)
Trước khi đi vào nội dung chi tiết, tôi nhắc lại vài điểm cơ bản về nguồn gốc tên các lệnh:
grep
: được đặt tên từ lệnh g/re/p (globally search for a regular expression and print matching lines) củaed
(nguồn: trust me, bro).ed
là một line editor được phát triển cho UNIX và vẫn còn tồn tại đến ngày nay (mặc dù hầu như không còn được sử dụng).sed
: được đặt tên theo cách nó hoạt động, stream editor.awk
: tên lệnh này được ghép từ chữ cái đầu của tên các tác giả (Aho, Weinberger, and Kernighan). Trong những người này, có lẽ Kernighan là cái tên quen thuộc hơn cả. Ông là tác giả chính của cuốn sách “The C Programming Language” kinh điển.
Trong nội dung bài viết này, tôi sử dụng file excuses.txt
(nội dung lấy từ trang http://programmingexcuses.com/) làm ví dụ minh họa. File được lưu trữ ở đây
grep
Lệnh grep
được dùng khi cần tìm kiếm từ nào đó:
$ grep test excuses.txt
I broke that deliberately to do some testing
I can't test everything
I must have been stress testing our production server
It can't be broken, it passes all unit tests
It works, but it's not been tested
Management insisted we wouldn't need to waste our time writing unit tests
That code seemed so simple I didn't think it needed testing
The unit test doesn't cover that eventuality
Nếu cụm từ tìm kiếm có chứa dấu cách, cần phải sử dụng dấu nháy. Ví dụ:
$ grep "a feature" excuses.txt
Actually, that's a feature
Lệnh grep
có thể nhận tùy chọn -i
để không phân biệt chữ cái hoa/thường. Ngoài ra, lệnh này có thể dùng ký tự đại diện trong tên file để tìm kiếm trên nhiều file khác nhau:
$ grep -i string *.txt
Cũng có thể sử dụng regular expression để tìm kiếm bằng cách thêm -E
hoặc dùng lệnh egrep
:
$ grep -E "[A-Z]{3,}" excuses.txt
Oh, you said you DIDN'T want that to happen?
THIS can't be the source of THAT
The WYSIWYG must have produced an invalid output
The third party API is not responding
$ egrep "[A-Z]{3,}" excuses.txt
Oh, you said you DIDN'T want that to happen?
THIS can't be the source of THAT
The WYSIWYG must have produced an invalid output
The third party API is not responding
Lệnh dưới đây sẽ tìm kiếm tất cả các cụm từ “feature” đồng thời in ra kết quả dòng tiếp theo của nó:
$ grep feature -A 1 excuses.txt
Actually, that's a feature
Did you check for a virus on your system?
--
That feature was slated for phase two
That feature would be outside of the scope
That important email must have been marked as spam
--
The project manager said no one would want that feature
The project manager told me to do it that way
Nếu muốn in ra nhiều dòng hơn, chỉ cần thay đổi con số trong lệnh trên. Để in ra các dòng phía trên, lệnh grep
cũng có sẵn tùy chọn -B
.
Lệnh grep
cũng có thể kết hợp với các lệnh khác thành pipe
$ cat excuses.txt | grep feature
Actually, that's a feature
That feature was slated for phase two
That feature would be outside of the scope
The project manager said no one would want that feature
sed
Tôi thường dùng lệnh sed
để thay một string thành string khác:
grep this excuses.txt | sed 's/this/that/g'
It's never shown unexpected behaviour like that before
Trong ví dụ trên, “this” sẽ được thay thế bằng “that” và in ra màn hình, /g
trong câu lệnh là để thay thế toàn bộ các string.
Lệnh sed
có thể thực hiện nhiều hành động phức tạp như:
- Chỉ thay thế các string xuất hiện trong 10 dòng đầu tiên:
$ sed '1,10 s/this/that/g' excuses.txt
- Chỉ thay thế đúng string xuất hiện ở lần thứ
n
:
$ sed 's/this/that/2' excuses.txt
Trong những ví dụ trên, kết quả của lệnh sed
sẽ được in ra màn hình còn nội dung file gốc không thay đổi. Nếu muốn ghi đè nội dung vào file gốc, cần thêm tùy chọn -i
:
$ sed -i 's/this/that/2' excuses.txt
Việc sử dụng -i
để ghi đè file rất nguy hiểm. Có thể sử dụng grep
để tìm kiếm các cụm từ phù hợp trước khi tiến hành thay thế để đảm bảo kết quả nhận được đúng như mong muốn.
awk
Lệnh awk
cung cấp rất nhiều tính năng để làm việc với dữ liệu text. Tôi thường sử dụng awk
với những dữ liệu có cấu trúc nhất định.
Khi awk
xử lý dữ liệu, nó sẽ xử lý theo từng dòng và cắt text thành các string ngăn cách bởi FS
(field separator – mặc định là dấu cách). Mỗi string được gọi là một field và được gán cho các biến $1
, $2
, … còn $0
chứa nội dung của cả dòng.
Cũng có thể áp dụng filter trong lệnh awk
, ví dụ:
$ cat excuses.txt | awk '/feature/ { print NR " - " $0 }'
1 - Actually, that's a feature
88 - That feature was slated for phase two
89 - That feature would be outside of the scope
113 - The project manager said no one would want that feature
Tham số truyền cho lệnh awk
sử dụng dấu nháy đơn.
- Lệnh này chỉ xử lý các dòng có chữ “feature”
- Sau đó sẽ xử lý theo những gì bên trong dấu ngoặc nhọn.
NR
là đại diện cho số dòng của dòng hiện tại- Thêm dấu
" - "
để ngăn cách kết quả
Các biến mà awk
cung cấp sẵn:
NR
: (Number of Record) Số dòng hiện tạiNF
: (Number of field) Số thứ tự của fieldFS
: field separator (mặc định là dấu cách)
Dưới đây là một ví dụ khác về việc xử lý dữ liệu có cấu trúc:
$ cat /etc/passwd | awk '/nologin/ { FS=":"; print $1 }'
bin
sys
man
lp
...
Cụ thể:
/nologin/
: chỉ xử lý những dòng có chứa “nologin”FS=": ";
sử dụng dấu hai chấm:
để ngăn cách thay vì dấu cách mặc địnhprint $1
: in ra string đầu tiên (ngăn cách bởi dấu:
)
Kết luận
Trên đây là những trường hợp điển hình về việc sử dụng các lệnh grep
, sed
, và awk
. Đó chỉ là những trường hợp thông dụng và đơn giản. Nếu dùng lệnh man
để tìm hiểu kỹ hơn về những lệnh này, chúng có thể được áp dụng cho những bài toán phức tạp hơn rất nhiều.
Welcome
Đây là thế giới của manhhomienbienthuy (naa). Chào mừng đến với thế giới của tôi!
Bài viết liên quan
Bài viết mới
Chuyên mục
Lưu trữ theo năm
Thông tin liên hệ
Cảm ơn bạn đã quan tâm blog của tôi. Nếu có bất điều gì muốn nói, bạn có thể liên hệ với tôi qua các mạng xã hội, tạo discussion hoặc report issue trên Github.