Lệnh grep
viết tắt của “global regular expression print” là một trong những lệnh mạnh nhất và thường được sử dụng trong Linux.
Grep tìm kiếm một hoặc nhiều tệp đầu vào cho các dòng khớp với một mẫu nhất định và ghi từng dòng khớp vào đầu ra tiêu chuẩn. Nếu không có tệp nào được chỉ định, grep
đọc từ đầu vào tiêu chuẩn, thường là đầu ra của lệnh khác.
Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách sử dụng lệnh grep
thông qua các ví dụ thực tế và giải thích chi tiết về các tùy chọn grep
GNU phổ biến nhất .
Cú pháp lệnh Grep
Trước khi đi vào cách sử dụng lệnh grep
, hãy bắt đầu bằng cách xem lại cú pháp cơ bản.
Biểu thức grep
có dạng sau:
grep [OPTIONS] PATTERN [FILE...]
Các mục trong ngoặc vuông là tùy chọn.
OPTIONS
– Không hoặc nhiều tùy chọn. Grep cung cấp một số tùy chọn kiểm soát hành vi của nó.PATTERN
– Mẫu tìm kiếm.FILE
– Không hoặc nhiều tên tệp đầu vào.
Để có thể tìm kiếm tệp, người dùng chạy lệnh phải có quyền truy cập đọc vào tệp.
Cách sử dụng Grep để Tìm kiếm Chuỗi trong Tệp
Cách sử dụng cơ bản nhất của lệnh grep
là tìm kiếm một chuỗi (văn bản) trong một tệp.
Ví dụ: để hiển thị các dòng từ file /etc/passwd
chứa chuỗi bash
bạn có thể sử dụng lệnh sau:
grep bash /etc/passwd
Đầu ra sẽ trông giống như thế này:
root:x:0:0:root:/root:/bin/bash linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
Nếu chuỗi bao gồm khoảng trắng, bạn cần đặt nó trong dấu ngoặc kép đơn hoặc kép:
grep "Gnome Display Manager" /etc/passwd
Đảo ngược Match (không bao gồm)
Để hiển thị các dòng không khớp với mẫu, sử dụng tùy chọn -v
(hoặc --invert-match
).
Ví dụ: để hiển thị các dòng từ file /etc/passwd
không chứa chuỗi nologin
, bạn có thể sử dụng lệnh sau:
grep -v nologin /etc/passwd
Output:
root:x:0:0:root:/root:/bin/bash colord:x:124:124::/var/lib/colord:/bin/false git:x:994:994:git daemon user:/:/usr/bin/git-shell linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
Cách sử dụng Grep để tìm kiếm chuỗi trong đầu ra lệnh
Thay vì chỉ định các tệp đầu vào, bạn có thể chuyển đầu ra của lệnh khác sang grep
, sau đó chỉ hiển thị các dòng khớp với một mẫu nhất định.
Ví dụ: để tìm hiểu các process đang chạy trên hệ thống của bạn với tư cách là người dùng www-data
bạn có thể sử dụng lệnh ps
sau :
ps -ef | grep www-data
Output:
www-data 18247 12675 4 16:00 ? 00:00:00 php-fpm: pool www root 18272 17714 0 16:00 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data www-data 31147 12770 0 Oct22 ? 00:05:51 nginx: worker process www-data 31148 12770 0 Oct22 ? 00:00:00 nginx: cache manager process
Bạn cũng có thể xâu chuỗi nhiều pipe theo lệnh. Như bạn có thể thấy trong đầu ra ở trên cũng có một dòng chứa process grep
. Nếu bạn không muốn dòng đó được hiển thị, hãy chuyển đầu ra grep
theo một cách khác như hiển thị bên dưới.
ps -ef | grep www-data | grep -v grep
Output:
www-data 18247 12675 4 16:00 ? 00:00:00 php-fpm: pool www root 18272 17714 0 16:00 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data www-data 31147 12770 0 Oct22 ? 00:05:51 nginx: worker process www-data 31148 12770 0 Oct22 ? 00:00:00 nginx: cache manager process
Tìm kiếm đệ quy
Để tìm kiếm đệ quy một mẫu, hãy sử dụng tùy chọn -r
(hoặc --recursive
). Điều này sẽ tìm kiếm thông qua tất cả các tệp trong thư mục được chỉ định, bỏ qua các symbolic link. Để theo tất cả các symbolic link , sử dụng tùy chọn -R
(hoặc --dereference-recursive
).
Trong ví dụ sau, tôi đang tìm kiếm chuỗi hocdevops.com
trong tất cả các tệp trong thư mục /etc
:
grep -r hocdevops.com /etc
Lệnh sẽ in các dòng khớp với tiền tố của đường dẫn đầy đủ đến tệp.
/etc/hosts:127.0.0.1 node2.hocdevops.com /etc/nginx/sites-available/hocdevops.com: server_name hocdevops.com www.hocdevops.com;
Nếu bạn sử dụng -r
thay cho tùy chọn -R
, grep
sẽ theo tất cả các liên kết tượng trưng (symbolic link):
grep -R hocdevops.com /etc
Lưu ý dòng cuối cùng của đầu ra. Dòng đó không được in trong ví dụ trên vì các tệp trong thư mục sites-enabled
của Nginx là các liên kết tượng trưng (symbolic link) đến các tệp cấu hình bên trong thư mục sites-available
.
/etc/hosts:127.0.0.1 node2.hocdevops.com /etc/nginx/sites-available/hocdevops.com: server_name hocdevops.com www.hocdevops.com; /etc/nginx/sites-enabled/hocdevops.com: server_name hocdevops.com www.hocdevops.com;
Chỉ hiển thị tên tệp
Để chặn đầu ra grep
mặc định và chỉ in tên của các tệp chứa mẫu phù hợp, bạn có thể sử dụng tùy chọn -l
(hoặc --files-with-matches
).
Ví dụ: để tìm kiếm trong tất cả các tệp kết thúc bằng .conf
trong thư mục làm việc hiện tại và chỉ in tên của các tệp chứa loại chuỗi hocdevops.com
:
grep -l hocdevops.com *.conf
Đầu ra sẽ trông giống như thế này:
tmux.conf haproxy.conf
Tùy chọn -l
thường được sử dụng kết hợp với các tùy chọn đệ quy -R
:
grep -Rl hocdevops.com /tmp
Tìm kiếm không đặc biệt
Theo mặc định, lệnh grep
tìm kiếm cả các trường hợp đặc biệt. Điều này có nghĩa là các ký tự chữ hoa và chữ thường được coi là đặc biệt.
Để bỏ qua khi tìm kiếm, sử dụng tùy chọn -i
(hoặc --ignore-case
).
Ví dụ: khi tìm kiếm Zebra
mà không có tùy chọn nào, lệnh sau sẽ không hiển thị bất kỳ đầu ra nào, tức là có các dòng khớp:
grep Zebra /usr/share/words
Nhưng nếu bạn thực hiện tìm kiếm không phân biệt chữ hoa bằng cách sử dụng tùy chọn -i
, nó sẽ khớp cả chữ in hoa và chữ thường:
grep -i Zebra /usr/share/words
Xác định chữ Zebra sẽ khớp với “zebra”, “ZEbrA” , hoặc bất kỳ sự kết hợp nào khác của chữ in hoa và chữ thường cho chuỗi đó.
zebra zebra's zebras
Tìm kiếm đầy đủ
Khi tìm kiếm trong các trang web, grep
cũng sẽ in các dòng trong đó.
grep gnu /usr/share/words
Output:
cygnus gnu interregnum lgnu9d lignum magnum magnuson sphagnum wingnut
Để chỉ trả về những dòng có chuỗi được chỉ định là toàn bộ từ (được bao quanh bởi các ký tự không phải từ), hãy sử dụng tùy chọn -w
(hoặc --word-regexp
).
Nếu bạn chạy cùng một lệnh như trên, bao gồm tùy chọn -w
,lệnh grep
sẽ chỉ trả về những dòng gnu
chỉ bao gồm dưới dạng một từ riêng biệt.
grep -w gnu /usr/share/words
Output:
gnu
Hiển thị số dòng
Để hiển thị số lượng dòng có chứa chuỗi khớp với mẫu, sử dụng tùy chọn -n
(hoặc --line-number
). Khi sử dụng tùy chọn này, grep
sẽ in các kết quả khớp với đầu ra tiêu chuẩn có tiền tố với số dòng được tìm thấy trên đó.
Ví dụ: để hiển thị các dòng từ file /etc/services
chứa chuỗi có tiền tố bash
với số dòng phù hợp, bạn có thể sử dụng lệnh sau:
grep -n 10000 /etc/services
Đầu ra bên dưới cho chúng ta thấy rằng các kết quả khớp được tìm thấy trên các dòng 10423 và 10424.
10423:ndmp 10000/tcp 10424:ndmp 10000/udp
Đếm các trường hợp match
Để in một số dòng phù hợp với đầu ra tiêu chuẩn, sử dụng tùy chọn -c
(hoặc --count
).
Trong ví dụ dưới đây, tôi đang đếm số lượng account có shell trong /usr/bin/zsh
.
grep -c '/usr/bin/zsh' /etc/passwd
Output:
4
Tìm kiếm nhiều chuỗi
Hai hoặc nhiều mẫu tìm kiếm có thể được nối bằng toán tử OR |
.
Theo mặc định, grep
diễn giải mẫu như một biểu thức chính quy cơ bản trong đó các ký tự meta như |
không có tác dụng do đó dấu gạch chéo ngược phải được sử dụng.
Trong ví dụ dưới đây, tôi đang tìm kiếm tất cả các lần xuất hiện của các từ fatal
, error
và critical
trong file log lỗi Nginx:
grep 'fatal\|error\|critical' /var/log/nginx/error.log
Nếu bạn sử dụng tùy chọn biểu thức chính quy mở rộng -E
(hoặc --extended-regexp
) thì toán tử |
sẽ không cần \
, như hiển thị bên dưới:
grep -E 'fatal|error|critical' /var/log/nginx/error.log
Quiet Mode
Tùy chọn -q
(hoặc --quiet
) cho grep
không in ra terminal (đầu ra tiêu chuẩn). Nếu quá trình tìm kiếm tìm thấy dữ liệu, lệnh sẽ thoát với trạng thái 0
. Điều này hữu ích khi sử dụng grep
trong các tập lệnh shell nơi bạn muốn kiểm tra xem một tệp có chứa một chuỗi hay không và thực hiện một hành động nhất định tùy thuộc vào kết quả.
Dưới đây là một ví dụ về việc sử dụng grep
trong quiet mode làm lệnh kiểm tra trong câu lệnh if
:
if grep -q PATTERN filename then echo pattern found else echo pattern not found fi
Biểu thức chính quy cơ bản
GNU Grep có hai bộ tính năng biểu thức chính quy, Cơ bản và Mở rộng. Theo mặc định, grep
sử dụng biểu thức chính quy cơ bản.
Khi được sử dụng trong chế độ biểu thức chính quy cơ bản, tất cả các ký tự khác ngoại trừ các ký tự meta, các biểu thức chính quy khớp với chính chúng. Dưới đây là danh sách các ký tự meta được sử dụng phổ biến nhất:
- Sử dụng
^
(dấu mũ) để khớp với biểu thức ở đầu một dòng. Trong ví dụ sau, chuỗi^kangaroo
sẽ chỉ khớp nếu nó xảy ra ở ngay đầu dòng.
grep "^kangaroo" file.txt
- Sử dụng
$
(đô la) để khớp với biểu thức ở cuối dòng. Trong ví dụ sau, chuỗikangaroo$
sẽ chỉ khớp nếu nó xảy ra ở cuối dòng.
grep "kangaroo$" file.txt
- Sử dụng
.
(dấu chấm) để khớp với bất kỳ ký tự đơn nào. Ví dụ: để khớp với bất cứ thứ gì bắt đầukan
sau đó có hai ký tự và kết thúc bằng chuỗiroo
, bạn có thể sử dụng mẫu sau:
grep "kan..roo" file.txt
- Sử dụng
[ ]
(ngoặc) để khớp với bất kỳ ký tự đơn nào được đặt trong ngoặc. Ví dụ: tìm các dòng có chứaaccept
hoặcaccent
, bạn có thể sử dụng mẫu sau:
grep "acce[np]t" file.txt
- Sử dụng
[^ ]
(ngoặc) để khớp với bất kỳ ký tự đơn nào được đặt trong ngoặc. Mẫu sau sẽ khớp với bất kỳ tổ hợp chuỗi nào có chứaco(any_letter_except_l)a
, chẳng hạn nhưcoca
,cobalt
v.v., nhưng sẽ không khớp với các dòng chứacola
:
grep "co[^l]a" file.txt
Để sử dụng ký tự đặc biệt, hãy sử dụng \
(dấu gạch chéo ngược).
Biểu thức chính quy mở rộng
Để diễn giải mẫu dưới dạng biểu thức chính quy mở rộng, hãy sử dụng tùy chọn -E
(hoặc --extended-regexp
). Các biểu thức chính quy mở rộng bao gồm tất cả các ký tự meta cơ bản, cùng với các ký tự meta bổ sung để tạo các mẫu tìm kiếm phức tạp và mạnh mẽ hơn. Dưới đây là một số ví dụ:
- Khớp và trích xuất tất cả các địa chỉ email từ một tệp nhất định:
grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file.txt
- Khớp và trích xuất tất cả các địa chỉ IP hợp lệ từ một tệp đã cho:
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt
Tùy chọn -o
được sử dụng để in chỉ chuỗi phù hợp.
In dòng trước khi match
Để in một số dòng cụ thể trước khi khớp dòng, sử dụng tùy chọn -B
(hoặc --before-context
).
Ví dụ: để hiển thị 5 dòng đầu trước khi khớp các dòng, bạn sẽ sử dụng lệnh sau:
grep -B 5 root /etc/passwd
In dòng sau khi match
Để in một số dòng cụ thể sau khi khớp dòng, sử dụng tùy chọn -A
(hoặc --after-context
).
Ví dụ: để hiển thị năm dòng sau các dòng khớp, bạn sẽ sử dụng lệnh sau:
grep -A 5 root /etc/passwd
Phần kết luận
Lệnh grep
Giúp cho bạn tìm kiếm trong các file một cách dễ dàng. Nếu bạn muốn tìm hiểu nhiều hơn nữa về Grep, truy cập trang Hướng dẫn sử dụng của Grep .
Nếu bạn có bất kỳ câu hỏi hoặc phản hồi, hãy để lại nhận xét.