Đọc và Xử Lý Văn Bản: grep, sed, awk và Bạn Bè
Đây là nhóm công cụ làm nên sức mạnh của dòng lệnh Linux. Đúng triết lý Unix (Bài 0), mỗi cái làm tốt một việc — xem, lọc, cắt, sắp, đếm, biến đổi văn bản. Học riêng từng cái, rồi Bài 6 sẽ ghép chúng lại bằng pipe.
Tạo một file mẫu trong lab để thực hành:
cd /tmp
printf "alice 90 math\nbob 75 science\ncarol 88 math\ndave 75 math\nalice 95 science\n" > scores.txt
Xem nội dung: cat, less, head, tail
cat scores.txt # in toàn bộ file ra màn hình
less scores.txt # xem file dài có phân trang (q để thoát, / để tìm)
head -2 scores.txt # 2 dòng đầu
tail -1 scores.txt # dòng cuối
cat hợp file ngắn; file dài thì less (cuộn bằng mũi tên/Space, thoát bằng q). head/tail lấy vài dòng đầu/cuối.
Đặc biệt hữu ích khi gỡ lỗi: tail -f theo dõi file log theo thời gian thực, in ra mỗi dòng mới được ghi:
tail -f /var/log/syslog # bám đuôi log, Ctrl+C để dừng
Lọc dòng: grep
grep in ra những dòng khớp một mẫu — công cụ bạn dùng nhiều nhất để tìm trong log và file:
grep math scores.txt # các dòng chứa "math"
grep -i MATH scores.txt # -i: không phân biệt hoa/thường
grep -v math scores.txt # -v: nghịch đảo (dòng KHÔNG chứa "math")
grep -c math scores.txt # -c: đếm số dòng khớp
grep -n math scores.txt # -n: kèm số dòng
grep -r "TODO" /duong/dan # -r: tìm đệ quy trong cả thư mục
alice 90 math
carol 88 math
dave 75 math
grep hiểu cả biểu thức chính quy (regex), ví dụ grep "^alice" scores.txt lọc dòng bắt đầu bằng "alice" (^ = đầu dòng).
Cắt cột: cut
Với dữ liệu có cột, cut lấy ra cột bạn cần:
cut -d ' ' -f1 scores.txt # -d ' ' tách bằng dấu cách, -f1 lấy cột 1
alice
bob
carol
dave
alice
-d chỉ ký tự ngăn cách (delimiter), -f chỉ số cột. Hay dùng với file CSV (-d ',') hoặc /etc/passwd (-d ':').
Sắp xếp và lọc trùng: sort, uniq
sort scores.txt # sắp theo thứ tự chữ cái
sort -k2 -n scores.txt # -k2 theo cột 2, -n sắp theo SỐ (không phải chữ)
cut -d ' ' -f1 scores.txt | sort | uniq # tên không trùng
cut -d ' ' -f1 scores.txt | sort | uniq -c # đếm số lần mỗi tên xuất hiện
Lưu ý: uniq chỉ gộp các dòng trùng liền kề, nên gần như luôn phải sort trước. uniq -c đếm số lần lặp — mẫu sort | uniq -c | sort -rn rất hay dùng để xếp hạng (ví dụ IP xuất hiện nhiều nhất trong log).
Đếm: wc
wc scores.txt # số dòng, số từ, số ký tự
wc -l scores.txt # chỉ đếm dòng (-l)
5 15 73 scores.txt
wc -l cực hay dùng để đếm: ví dụ grep error log | wc -l đếm số lỗi.
Biến đổi văn bản: sed
sed (stream editor) sửa văn bản theo luồng, phổ biến nhất là thay thế:
sed 's/math/TOAN/g' scores.txt # thay "math" -> "TOAN" trên mọi dòng
alice 90 TOAN
bob 75 science
carol 88 TOAN
...
Cú pháp s/cũ/mới/g: s = substitute, g = global (mọi lần xuất hiện trên dòng, không chỉ lần đầu). Mặc định sed in ra kết quả chứ không sửa file gốc; thêm -i để sửa thẳng vào file (sed -i 's/.../.../g' file) — cẩn thận vì nó ghi đè.
Xử lý theo cột: awk
awk mạnh hơn cho dữ liệu cột: nó tách mỗi dòng thành các trường $1, $2... và cho bạn lọc, tính toán:
awk '{print $1, $2}' scores.txt # in cột 1 và 2
awk '$2 > 80 {print $1, $2}' scores.txt # chỉ dòng có cột 2 > 80
alice 90
carol 88
alice 95
$2 > 80 là điều kiện, {print ...} là hành động. awk còn cộng dồn, tính trung bình, đếm theo nhóm... — cả một ngôn ngữ nhỏ. Với người mới, nhớ "tách cột thành $1 $2 ... rồi lọc/in" là đủ dùng phần lớn.
Khi nào dùng cái nào:
grepđể lọc dòng theo mẫu;cutđể lấy cột đơn giản;sedđể thay thế/biến đổi text;awkkhi cần xử lý theo cột có điều kiện/tính toán. Chồng lấn nhau, nhưng đây là điểm mạnh của mỗi cái.
🧹 Dọn dẹp
rm -f scores.txt
Tổng kết
Bạn có một bộ công cụ xử lý văn bản: cat/less/head/tail (xem, kèm tail -f theo dõi log), grep (lọc dòng), cut (lấy cột), sort/uniq (sắp + lọc trùng), wc (đếm), sed (thay thế), awk (xử lý theo cột). Mỗi cái nhỏ và chuyên một việc.
Sức mạnh thật sự đến khi ghép chúng lại: đầu ra của cái này thành đầu vào của cái kia. Bài 6 giải thích cơ chế đó — pipe và redirect — cùng ba luồng dữ liệu stdin/stdout/stderr đứng sau.