Sử dụng grep và biểu thức chính quy để tìm kiếm text

Bài viết được lược dịch từ nguồn: Using Grep & Regular Expressions to Search for Text Patterns in Linux

1. Giới thiệu

grep là một trong những câu lệnh hữu ích và linh hoạt khi làm việc ở môi trường Linux. Nó là chữ viết tắt của cụm từ global regular expression print. Với khả năng sắp xếp đầu vào dựa trên những quy tắc tổ hợp phức tạp, grep trở thành một mối nối phổ biến trong nhiều chuỗi câu lệnh Linux. Trong bài viết này, chúng ta sẽ cùng tìm hiểu một vài tùy chọn thường dùng với lệnh grep và điểm qua một chút về cách sử dụng biểu thức chính quy khi làm việc với câu lệnh này.

2. Cách sử dụng cơ bản

Ở dạng đơn giản nhất, grep có thể sử dụng để so khớp một xâu ký tự với một file text. Kết quả là nó sẽ in ra màn hình terminal những dòng có chứa xâu ký tự đó.

Ví dụ minh họa: chúng ra sẽ sử dụng grep để tìm kiếm những dòng bao gồm từ GNU ở trong file giấy phép GNU General Public License version 3 có sẵn trên hệ điều hành Ubuntu:

cd /usr/share/common-licenses
grep "GNU" GPL-3
                    GNU GENERAL PUBLIC LICENSE
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
  Developers that use the GNU GPL protect your rights with two steps:
  "This License" refers to version 3 of the GNU General Public License.
  13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
...

Câu lệnh grep vừa thực hiện gồm 2 tham số: tham số đầu tiên, GNU, là khuôn mẫu (pattern) chúng ta đang tìm kiếm; tham số thứ 2, GPL-3 là file đầu vào.

Những tùy chọn phổ biến

Theo mặc định, grep sẽ tìm kiếm chính xác từ file đầu vào xâu ký tự mà chúng ta cung cấp và trả về những dòng có chứa xâu này. Câu lệnh này có thể trở nên linh hoạt và hữu ích hơn nữa bằng cách bổ sung thêm một vài tùy chọn khác (còn gọi là các flag).

Nếu muốn bỏ qua việc phân biệt chữ hoa, chữ thường khi tìm kiếm với grep, chúng ta có thể chỉ định tùy chọn -i hoặc --ignore-case.

Ví dụ, vẫn với file GPL-3 ở trên, câu lệnh sau sẽ in ra màn hình những dòng xuất hiện từ license, không phân biệt chữ hoa, chữ thường:

grep -i "license" GPL-3
                    GNU GENERAL PUBLIC LICENSE
 of this license document, but changing it is not allowed.
  The GNU General Public License is a free, copyleft license for
  The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
(1) assert copyright on the software, and (2) offer you this License
  "This License" refers to version 3 of the GNU General Public License.
  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
...
...

Rõ ràng, kết quả in ra là những dòng bao gồm ít nhất một trong các từ LICENSE, license hoặc License. Nếu có dòng nào có chứa từ LiCeNsE thì nó cũng được hiển thị ra màn hình.

Một tình huống khác, nếu chúng ta muốn những dòng in ra không chứa khuôn mẫu truyền vào lệnh grep thì cần kết hợp với tùy chọn -v hoặc --invert-match.

Ví dụ, bạn có thể tìm kiếm những dòng không bao gồm từ the trong giấy phép BSD có sẵn trên một máy tính cài hệ điều hành Ubuntu, được đặt cùng thư mục với giấy phép GPL-3 bằng câu lệnh sau:

grep -v "the" BSD
All rights reserved.

Redistribution and use in source and binary forms, with or without
are met:
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

Vì chúng ta không kết hợp với tùy chọn --ignore-case, kết quả trả về bao gồm cả những dòng có chứa từ THE.

Để biết được những dòng kết quả là dòng thứ mấy trong file đầu vào, chúng ta cần kết hợp với tùy chọn -n hoặc là --line-number, ví dụ:

grep -vn "the" BSD
2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13:   may be used to endorse or promote products derived from this software
14:   without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

3. Biểu thức chính quy

Theo định nghĩa, biểu thức chính quy (regular expression) là một xâu ký tự đặc tả một khuôn mẫu dùng để tìm kiếm.

Những ứng dụng và ngôn ngữ lập trình khác nhau cài đặt biểu thức chính quy hơi khác nhau một chút. Dưới đây, chúng ta sẽ sử dụng một vài cú pháp của biểu thức này, kết hợp với lệnh grep để có thể tạo ra những câu lệnh tìm kiếm văn bản hiệu quả hơn.

So khớp trực tiếp

Phương pháp này được sử dụng để so khớp chính xác tất cả những ký tự, bao gồm chữ cái, chữ số, những ký tự loại khác.

Ở ví dụ trên, khi tìm kiếm với từ GNUthe, thực sự thì chúng ta đang tìm kiếm với dạng biểu thức chính quy đơn giản nhất. Nó sẽ so khớp chính xác xâu ký tự GNUthe với những tổ hợp xuất hiện trong file đầu vào.

Tốt hơn hết, bạn nên hình thành suy nghĩ là đang thao tác với những xâu ký tự hơn là làm việc với các từ. Đây là một điểm khác biệt đáng chú ý khi chúng ta tìm hiểu sâu hơn về những khuôn mẫu phức tạp.

So khớp neo

Ký tự neo là những ký tự đặc biệt, không chỉ so khớp ký tự, mà còn chỉ định được khuôn mẫu so khớp truyền vào cần được thực hiện ở vị trí nào.

Ví dụ, nếu chỉ muốn tìm kiếm những dòng mà có ba ký tự GNU ở đầu dòng, bạn có thể sử dụng ký tự neo ^ đứng trước tham số xâu ký tự trong câu lệnh grep:

grep "^GNU" GPL-3
GNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published

Tương tự, với ký tự $, chúng ta có thể viết liền sau một xâu ký tự để chỉ ra rằng việc so khớp chỉ hợp lệ khi nó được thực hiện ở cuối một dòng. Câu lệnh để in ra màn hình những dòng kết thúc với từ and:

grep "and$" GPL-3
that there is no warranty for this free software.  For both users' and
  The precise terms and conditions for copying, distribution and
License.  Each licensee is addressed as "you".  "Licensees" and
receive it, in any medium, provided that you conspicuously and
    alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and

So khớp ký tự bất kỳ

Dấu chấm . được sử dụng trong biểu thức chính quy với ý nghĩa đại diện cho bất kỳ ký tự nào. Ví dụ, nếu muốn so khớp những xâu ký tự được bắt đầu với 2 ký tự, nối tiếp là xâu cept, bạn có thể viết như sau:

grep "..cept" GPL-3
use, which is precisely where it is most unacceptable.  Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the
License by making exceptions from one or more of its conditions.
form of a separately written license, or stated as exceptions;
  You may not propagate or modify a covered work except as expressly
  9. Acceptance Not Required for Having Copies.
...
...

Kết quả trả về là những dòng có chứa cả xâu ký tự accept, except và những biến thể của 2 xâu này. Dễ dàng suy ra, nếu dòng nào có chứa xâu z2cept thì nó cũng được tìm thấy và hiển thị ra màn hình terminal.

Sử dụng ngoặc vuông

Bằng cách đặt một nhóm ký tự vào trong dấu đóng mở ngoặc vuông [ ], chúng ta có thể chỉ định ký tự ở vị trí đó là một trong những ký tự được liệt kê ở trong ngoặc.

Ví dụ, nếu muốn tìm những dòng bao gồm xâu ký tự too hoặc two, bạn có thể chỉ định những biến thể này một cách ngắn gọn bằng cú pháp sau:

grep "t[wo]o" GPL-3
your programs, too.
freedoms that you received.  You must make sure that they, too, receive
  Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.
System Libraries, or general-purpose tools or generally available free
...
...

Cú pháp sử dụng dấu ngoặc vuông cũng cho phép chúng ta linh hoạt trong việc định nghĩa biểu thức tìm kiếm. Bạn có thể có một khuôn mẫu khớp với mọi thứ, ngoại từ những ký tự trong dấu ngoặc vuông bằng cách bắt đầu danh sách các ký tự trong ngoặc với một dấu mũ ^.

Câu lệnh sau sẽ tìm những dòng có chứa xâu ký tự .code mà không bao gồm code:

grep "[^c]ode" GPL-3
  1. Source Code.
    model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:

Bạn có thể để ý rằng, ở dòng thứ 2 trong kết quả in ra màn hình có bao gồm xâu ký tự code. Đây không phải là khuyết điểm của biểu thức chính quy hay là lệnh grep. Lý do là vì ở đầu dòng này, xâu ký tự so khớp mode là một phần của từ model đã được máy tính tìm thấy.

Một tính năng hữu ích khác của cú pháp ngoặc vuông là bạn có thể chỉ định một dải các ký tự thay vì liệt kê từng ký tự. Nếu muốn tìm những dòng được bắt đầu với một chữ cái viết hoa, chúng ta có thể sử dụng khuôn mẫu sau:

grep "^[A-Z]" GPL-3
GNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License.  Each licensee is addressed as "you".  "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
Corresponding Source conveyed under this section must be accompanied
...
...

Cách sử dụng ký tự *

Một ký tự hữu ích khác nữa có thể sử dụng trong biểu thức chính quy là dấu *, mang ý nghĩa là cho phép lặp lại ký tự đứng ngay trước nó 0 hoặc nhiều lần.

Để tìm những dòng bao gồm dấu đóng, mở ngoặc tròn, ở giữa hai dấu này bao gồm các chữ cái và khoảng trắng đơn lẻ thì ta có thể thực hiện câu lệnh sau:

grep "([A-Za-z ]*)" GPL-3
 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
    (including a physical distribution medium), accompanied by the
    (including a physical distribution medium), accompanied by a
    place (gratis or for a charge), and offer equivalent access to the
...
...

4. Kết luận

Sẽ có nhiều lần mà câu lệnh grep sẽ trở nên hữu ích trong việc tìm kiếm các khuôn mẫu từ những file mà bạn đang có. Rèn luyện để trở nên quen thuộc với cú pháp và những tùy chọn của câu lệnh này là điều đáng làm bởi vì nó sẽ giúp bạn tiết kiệm rất nhiều thời gian khi xử lý file bằng giao diện dòng lệnh.

Biểu thức chính quy là một công cụ còn linh hoạt hơn nữa, và không chỉ kết hợp giới hạn với lệnh grep, nó còn được sử dụng phổ biến trong các chương trình khác. Nhiều trình soạn thảo văn bản đã cài đặt công cụ này để phục vụ cho việc tìm kiếm text. Phần lớn những ngôn ngữ lập trình hiện đại sử dụng biểu thức chính quy để thực hiện những thủ tục trên những đoạn dữ liệu xác định. Tóm lại, cũng giống như grep và hơn thế nữa, khả năng sử dụng hiệu quả biểu thức chính quy sẽ mang lại rất nhiều lợi ích cho bạn khi lập trình và làm việc với máy tính.

5. Một số tài liệu tham khảo khác