Post

Grep – Khi Ctrl+F còn quá yếu

Grep – Khi Ctrl+F còn quá yếu

Có bao giờ bạn cảm thấy như một thám tử đang lục tung cả một thư viện để tìm một câu trích dẫn mà mình nhớ mang máng không? Hoặc như Sherlock Holmes đang cần tìm một manh mối nhỏ xíu trong một đống tài liệu khổng lồ? Nếu có, thì hôm nay mình sẽ giới thiệu với bạn một “thám tử” siêu đẳng của thế giới command line - grep.

Grep là viết tắt của “Global Regular Expression Print” - nghe có vẻ hầm hố phải không? Nhưng đừng để cái tên làm bạn sợ, vì grep thực chất là một trong những công cụ thân thiện và hữu ích nhất mà bạn sẽ gặp trong terminal.

Grep là gì và tại sao nó quan trọng?

Grep là một công cụ command line được sử dụng để tìm kiếm văn bản theo pattern (mẫu) trong các file hoặc input stream. Nó như một chiếc kính lúp siêu mạnh giúp bạn tìm ra những gì mình cần trong biển thông tin bao la.

Tưởng tượng bạn có một file log với hàng nghìn dòng, và bạn chỉ muốn tìm những dòng chứa từ “ERROR”. Thay vì phải lăn chuột đến tê liệt hoặc dùng Ctrl+F như một người nguyên thủy, grep sẽ giúp bạn làm điều này chỉ trong một giây.

Cú pháp cơ bản

1
grep [options] pattern [file...]

Đơn giản như cơm ăn áo mặc. Bạn cho grep biết:

  • Bạn muốn tìm gì (pattern)
  • Tìm ở đâu (file)
  • Tìm như thế nào (options)

Những ví dụ cơ bản để bắt đầu

Tìm kiếm đơn giản

1
grep "hello" file.txt

Lệnh này sẽ tìm tất cả các dòng chứa từ “hello” trong file.txt. Đơn giản như việc hỏi “Có ai tên Hello không?” trong một đám đông.

Tìm kiếm không phân biệt chữ hoa chữ thường

1
grep -i "HELLO" file.txt

Option -i (ignore case) giúp grep trở thành một thám tử không kén chọn - dù bạn viết “hello”, “HELLO”, hay “HeLLo” thì nó cũng tìm được hết.

Tìm kiếm trong nhiều file

1
grep "error" *.log

Lệnh này sẽ tìm từ “error” trong tất cả các file có đuôi .log. Như việc hỏi cùng lúc tất cả các file log: “Ai trong các bạn có chứa lỗi không?”

Hiển thị số dòng

1
grep -n "function" code.js

Option -n sẽ hiển thị số dòng, rất hữu ích khi bạn cần biết chính xác lỗi ở dòng nào để debug.

Các option phổ biến và hữu ích

Option -v (invert match)

1
grep -v "comment" file.txt

Tìm tất cả các dòng KHÔNG chứa từ “comment”. Đây là cách grep nói “Tôi muốn mọi thứ trừ cái này”.

Option -c (count)

1
grep -c "TODO" *.js

Đếm số dòng chứa “TODO” trong các file JavaScript. Rất hữu ích để biết bạn còn bao nhiêu việc chưa làm (và có thể sẽ khiến bạn khóc).

Option -r hoặc -R (recursive)

1
grep -r "password" /var/log/

Tìm kiếm đệ quy trong tất cả các file và thư mục con. Như việc khám phá từng ngóc ngách của một ngôi nhà để tìm chìa khóa bị mất.

Option -l (files with matches)

1
grep -l "import" *.py

Chỉ hiển thị tên file chứa pattern, không hiển thị nội dung. Hữu ích khi bạn chỉ cần biết “file nào có chứa thứ tôi tìm”.

Option -A, -B, -C (context)

1
grep -A 3 -B 2 "error" log.txt
  • -A 3: Hiển thị 3 dòng sau dòng match
  • -B 2: Hiển thị 2 dòng trước dòng match
  • -C 5: Hiển thị 5 dòng trước và sau (context)

Như việc xem bối cảnh xung quanh một sự kiện để hiểu rõ hơn chuyện gì đã xảy ra.

Regular Expressions - Vũ khí bí mật của Grep

Đây chính là nơi grep trở nên thực sự mạnh mẽ. Regular expressions (regex) là một ngôn ngữ pattern matching cho phép bạn tìm kiếm theo các mẫu phức tạp.

Một số metacharacter cơ bản:

  • . : Khớp với bất kỳ ký tự nào
  • * : Khớp với 0 hoặc nhiều ký tự trước đó
  • ^ : Bắt đầu dòng
  • $ : Kết thúc dòng
  • [] : Tập hợp ký tự
  • \ : Escape character

Ví dụ thực tế:

1
2
3
4
5
6
7
8
9
10
11
# Tìm các dòng bắt đầu bằng "Error"
grep "^Error" log.txt

# Tìm các dòng kết thúc bằng dấu chấm câu
grep "\.$" document.txt

# Tìm các số điện thoại (pattern đơn giản)
grep "[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\}" contacts.txt

# Tìm địa chỉ email
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" emails.txt

Extended Regular Expressions với egrep hoặc grep -E

Khi bạn cần sử dụng các pattern phức tạp hơn, grep -E (hoặc egrep) sẽ là bạn thân:

1
2
3
4
5
6
7
8
# Tìm các dòng chứa "cat" hoặc "dog"
grep -E "cat|dog" animals.txt

# Tìm các từ có 3-5 ký tự
grep -E "\b[a-zA-Z]{3,5}\b" text.txt

# Tìm IP addresses
grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" network.log

Những mẹo và thủ thuật hay ho

Tìm kiếm trong output của command khác

1
2
ps aux | grep "nginx"
cat /var/log/syslog | grep "error" | tail -10

Highlight kết quả với màu sắc

1
grep --color=always "pattern" file.txt

Tìm kiếm binary files

1
grep -a "text" binary_file

Exclude thư mục hoặc file pattern

1
2
grep -r --exclude-dir=node_modules "TODO" .
grep -r --exclude="*.min.js" "function" .

Sử dụng với find để tìm kiếm mạnh mẽ hơn

1
find . -name "*.log" -exec grep -l "ERROR" {} \;

Các biến thể của grep

fgrep (hoặc grep -F)

Tìm kiếm fixed strings, không sử dụng regex. Nhanh hơn khi bạn không cần pattern matching.

1
fgrep "literal.string.with.dots" file.txt

zgrep

Tìm kiếm trong các file đã được nén gzip mà không cần giải nén.

1
zgrep "error" compressed.log.gz

rgrep

Tương đương với grep -r, tìm kiếm đệ quy.

Những lỗi thường gặp và cách tránh

Quên escape special characters

1
2
3
4
5
# Sai
grep "192.168.1.1" file.txt  # Dấu chấm được hiểu là wildcard

# Đúng  
grep "192\.168\.1\.1" file.txt

Không sử dụng quotes

1
2
3
4
5
# Sai
grep hello world file.txt  # Shell sẽ hiểu nhầm

# Đúng
grep "hello world" file.txt

Quên option -r khi tìm kiếm trong thư mục

1
2
3
4
5
# Sai
grep "pattern" /path/to/directory/  # Chỉ tìm trong directory chứ không phải files bên trong

# Đúng
grep -r "pattern" /path/to/directory/

Kết hợp grep với các command khác

Grep thực sự tỏa sáng khi được kết hợp với các command khác thông qua pipes:

1
2
3
4
5
6
7
8
# Tìm process và kill
ps aux | grep "nginx" | awk '{print $2}' | xargs kill

# Tìm file lớn nhất chứa pattern
grep -r "TODO" . | wc -l

# Phân tích log files
tail -f /var/log/apache2/access.log | grep "404" | cut -d' ' -f1 | sort | uniq -c

Performance Tips

Sử dụng --include--exclude

1
2
3
4
5
# Chỉ tìm trong Python files
grep -r --include="*.py" "import" .

# Loại trừ các file không cần thiết
grep -r --exclude-dir=".git" --exclude="*.pyc" "function" .

Sử dụng grep -F cho literal strings

Khi bạn tìm kiếm exact strings không cần regex, -F sẽ nhanh hơn.

Sử dụng pgrep cho processes

1
pgrep -f "nginx"  # Nhanh hơn ps aux | grep nginx

Kết luận

Grep là một trong những công cụ không thể thiếu trong arsenal của bất kỳ developer, system administrator, hay bất cứ ai làm việc với command line. Nó đơn giản nhưng mạnh mẽ, linh hoạt nhưng đáng tin cậy.

Từ việc tìm kiếm đơn giản đến pattern matching phức tạp, từ debug code đến phân tích log files, grep luôn sẵn sàng là người bạn đồng hành trung thành. Và điều tuyệt vời nhất? Nó có mặt trên hầu hết mọi hệ thống Unix-like, từ Linux đến macOS.

Vậy nên lần tới khi bạn cần tìm kim trong đống cỏ khô (hoặc một dòng code trong đống file), hãy nhớ đến grep - thám tử siêu đẳng của command line. Nó sẽ không bao giờ làm bạn thất vọng, trừ khi bạn quên dấu ngoặc kép trong regex pattern =))


This post is licensed under CC BY 4.0 by the author.