Biểu thức chính quy (hay Regular Expression) là một mẫu quy tắc dùng để lọc văn bản. Bài hôm nay chúng ta sẽ tìm hiểu lệnh grep và sử dụng biểu thức chính quy.
Lệnh grep
Lệnh grep giống như một lệnh tìm kiếm trên file văn bản. Kết quả sẽ hiển thị ngay trên màn hình command line theo dòng nào có chứa chuỗi sẽ hiển thị cả dòng trong file đó ra và chuỗi đó sẽ được highlight.
Cách sử dụng:
grep [OPTION] PATTERN [FILE...]
Sử dụng lệnh grep
để tìm kiếm user root:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
Đếm số kết quả
Sử dụng thêm option -c
hoặc --count
để hiển thị số kết quả được tìm thấy.
$ grep -c root /etc/passwd
3
Tìm kiếm không phân biệt hoa thường
Sử dụng lệnh grep
option -i
để tìm kiếm chính xác chuỗi không phân biệt viết thường hay viết hoa:
$ grep -i root /etc/passwd
Tìm kiếm với danh sách từ khóa được lưu ở một file khác
Giả sử ta có file accounts.txt
chứa danh sách các từ khóa cần tìm kiếm:
$ cat accounts.txt
sshd
Christine
nfsnobody
Sử dụng lệnh grep
với tham số -f
để chỉ định file chứa danh sách từ khóa.
$ grep -F -f accounts.txt /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
Christine:x:1001:1001::/home/Christine:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
Tìm kiếm chính xác từ
Mặc định lệnh grep
sẽ trả về các kết quả chứa từ khóa, bao gồm từ khóa đó có thể là chuỗi con. Để tìm chính xác một từ, sử dụng tham số -w
.
$ grep -w root /etc/passwd
Tìm kiếm trong tất cả các thư mục con
Đôi khi ta không biết file cần tìm nằm trong thư mục nào, hoặc thư mục có rất nhiều file, thì ta có thể sử dụng option -r
để tìm kiếm tất cả các file trong tất cả các thư mục cũng như thư mục con.
$ grep -r abc /var/www/html
Tìm kiếm ngược
Để tìm tất cả các dòng không chứa từ khóa đó, sử dụng option -v
.
$ grep -v root /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
Christine:x:1001:1001::/home/Christine:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
Chỉ hiển thị tên file
Sử dụng option -l
để hiển thị tên các file chứa nội dung cần tìm kiếm.
$ grep -l root /etc
passwd
Hiển thị số thứ tự của dòng kết quả
Nếu giả sử một file có rất rất nhiều dòng, khi tìm kiếm, ta không thể xác định được dòng đó ở vị trí nào trong file thì có thể sử dụng option -n
để đánh dấu số thứ tự của mỗi dòng trong kết quả:
$ grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
5:operator:x:11:0:operator:/root:/sbin/nologin
Biểu thức chính quy cơ bản
Regular Expression hay còn gọi là biểu thức chính quy được dùng để xử lý chuỗi nâng cao thông qua biểu thức riêng của nó, những biểu thức này sẽ có những nguyên tắc riêng và bạn phải tuân theo nguyên tắc đó thì biểu thức mới hoạt động được.
Dấu chấm (.) thể hiện một ký tự, dấu chấm theo sau là dấu hoa thị (.*) tượng trưng cho nhiều ký tự.
$ grep daemon.*nologin /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
daemon:/dev/null:/sbin/nologin
Sử dụng dấu nón (^) để tìm kiếm nội dung bắt đầu bằng từ cho trước.
$ grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash
Sử dụng dấu ($) để tìm kiếm nội dung kết thúc bằng từ cho trước. Tương tự như ví dụ trên.
Nếu muốn lọc ra những dòng không phải là dòng trống, sử dụng kết hợp tham số -v
và regular expression ^$
.
$ grep -v ^$ /etc/passwd
Một số class được định nghĩa sẵn:
[:alnum:]
: khớp với tất cả các ký tự số cùng với ký tự chữ cái không phân biệt hoa thường. Tương đương với [0-9A-Za-z].[:alpha:]
: khớp với tất cả ký tự chữ cái không phân biệt hoa thường, tương đương [A-Za-z].[:blank:]
: khớp với các ký tự khoảng trắng, kể cả dấu tab.[:digit:]
: bao gồm các ký tự số từ 0 – 9, tương đương [0-9].[:lower:]
: khớp với các ký tự chữ cái viết thường.[:punct:]
: khớp với các ký tự dấu câu như !, #, $ và @.[:space:]
: khớp với ký tự dấu cách, dấu tab, khoảng trắng.[:upper:]
: khớp với tất cả các ký tự chữ cái in hoa, tương đương [A-Z].
Cách sử dụng các class này như sau:
Giả sử có file random.txt:
$ cat random.txt
42
Flat Land
Schrodinger's Cat
0010 1010
0000 0010
Dùng lệnh grep
với class để lọc ra những dòng chỉ chứa ký tự số:
$ grep [[:digit:]] random.txt
42
0010 1010
0000 0010
Ngoài ra ta có thể sử dụng dấu sọc đứng (|) để thay thế cho “hoặc”. Ví dụ sau sẽ thực hiện tìm kiếm các dòng bắt đầu bằng “root” hoặc bắt đầu bằng “dbus“.
$ grep -E "^root|^dbus" /etc/passwd
root:x:0:0:root:/root:/bin/bash
dbus:x:81:81:System message bus:/:/sbin/nologin
Hoặc một ví dụ phức tạp khác:
$ grep "(daemon|s).*nologin" /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
Xem thêm Bài 4: Một số lệnh thao tác với tệp văn bản trong Linux.
Comments 1