hoatranlab.io.vn Zalo: 0917516878 Hotline: 0917516878 [email protected]
HoaTranLab Logo HoaTranLab
Linux Bible 11th Edition • Chapter 5

Working with Text Files

Xem, tìm kiếm, lọc, sắp xếp và chỉnh sửa file văn bản trong Linux với các công cụ mạnh mẽ: grep, sed, awk, vim, sort, cut và nhiều hơn.

Mục Tiêu Chương 5

Xem nội dung file

Dùng cat, less, more, head, tail để hiển thị nội dung. tail -f theo dõi file log real-time. nl đánh số dòng.

Tìm kiếm với grep

grep tìm pattern trong file với regex. Dùng -i (case insensitive), -r (recursive), -n (line number), -v (invert), -E (extended regex).

Sắp xếp và lọc

sort sắp xếp dòng, uniq loại bỏ trùng lặp, wc đếm ký tự/từ/dòng, cut trích xuất cột, tr thay thế ký tự.

sed – Stream Editor

sed xử lý văn bản theo dòng: thay thế, xóa, thêm, in. Pattern: s/old/new/g, d (delete), p (print), /range/ lọc.

awk – Pattern Processing

awk xử lý file có cấu trúc cột. $1, $2, $NF là các trường, $0 là dòng. Hỗ trợ điều kiện, vòng lặp, tính toán.

Vim/Nano Editor

Vim: 3 chế độ (normal/insert/command). Nano: đơn giản, phím tắt hiển thị ở dưới. Biết mở, lưu, thoát cơ bản.

Lý Thuyết: Text Processing Tools

1. Xem File: cat, less, head, tail

Terminal – Xem nội dung file

$ cat /etc/hostname

myserver

$ cat -n /etc/hosts

1 127.0.0.1 localhost

2 ::1 localhost

$ head -5 /var/log/messages

# Hiện 5 dòng đầu (mặc định 10)

$ tail -20 /var/log/messages

# Hiện 20 dòng cuối

$ tail -f /var/log/messages

# Theo dõi real-time (Ctrl+C để thoát)

$ less /etc/passwd

# Xem cuộn lên/xuống, tìm kiếm /pattern, q thoát

2. grep – Tìm kiếm Pattern

grep (Global Regular Expression Print) tìm dòng khớp pattern trong file. Hỗ trợ basic regex (grep) và extended regex (grep -E hoặc egrep).

Terminal – grep

$ grep "root" /etc/passwd

root:x:0:0:root:/root:/bin/bash

$ grep -i "ssh" /var/log/messages | tail -5

# -i: case insensitive

$ grep -n "error" /var/log/syslog

# -n: hiển thị số dòng

$ grep -r "password" /etc/ 2>/dev/null

# -r: tìm đệ quy trong thư mục

$ grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"

# -v: loại bỏ dòng khớp; lọc comment và dòng trống

$ grep -E "^(root|chris):" /etc/passwd

# -E: extended regex (alternation |)

$ grep -c "Failed" /var/log/secure

23

# -c: chỉ đếm số dòng khớp

3. sort, uniq, wc, cut, tr

Terminal – Text utilities

$ cat /etc/passwd | cut -d: -f1 | sort

# cut: tách theo delimiter ':', lấy cột 1; sort: sắp xếp

$ sort -t: -k3 -n /etc/passwd | head -5

# Sắp xếp theo cột 3 (UID) dạng số

$ wc /etc/passwd

42 84 2156 /etc/passwd

# 42 dòng, 84 từ, 2156 ký tự

$ cat /etc/passwd | cut -d: -f7 | sort | uniq -c | sort -rn

36 /sbin/nologin

3 /bin/bash

# Đếm số lần xuất hiện của mỗi shell

$ echo "Hello World" | tr 'a-z' 'A-Z'

HELLO WORLD

$ echo "hello world" | tr -s ' '

hello world

# tr -s: gộp nhiều ký tự thành 1

4. sed – Stream Editor

sed xử lý văn bản theo từng dòng, dùng để thay thế, xóa, thêm, lọc nội dung. Pattern cơ bản: s/old/new/flags

Terminal – sed

$ echo "Hello World" | sed 's/World/Linux/'

Hello Linux

$ sed 's/http/https/g' urls.txt

# /g: thay tất cả lần xuất hiện trên dòng

$ sed -i 's/old_hostname/new_hostname/g' /etc/hosts

# -i: sửa trực tiếp file

$ sed '/^#/d' /etc/ssh/sshd_config

# d: xóa dòng bắt đầu bằng #

$ sed -n '5,10p' /etc/passwd

# In dòng 5 đến 10

$ sed '3a\New line after line 3' file.txt

# Thêm dòng sau dòng 3

5. awk – Xử lý dữ liệu có cấu trúc

Terminal – awk

$ awk -F: '{print $1, $3}' /etc/passwd

root 0

bin 1

# -F: delimiter, $1=col1 $3=col3

$ awk -F: '$3 >= 1000 {print $1}' /etc/passwd

chris

# Chỉ in user với UID >= 1000

$ df -h | awk 'NR>1 {print $5, $6}'

30% /

5% /boot

# NR>1: bỏ qua dòng header

$ awk '{sum += $1} END {print "Total:", sum}' numbers.txt

# Tính tổng cột số 1

$ ps aux | awk '{print $1}' | sort | uniq -c | sort -rn | head

# Đếm process theo user

Vim Editor và diff

6. Vim – Trình soạn thảo mạnh mẽ

Vim có 3 chế độ chính: Normal (di chuyển, lệnh), Insert (gõ text), Command (lưu, thoát, tìm kiếm).

Lệnh VimChức năng
i, a, oVào Insert mode: trước/sau con trỏ/dòng mới
EscThoát Insert mode, về Normal mode
:wLưu file
:qThoát (lỗi nếu chưa lưu)
:wq hoặc :xLưu và thoát
:q!Thoát không lưu (force quit)
dd, yy, pXóa dòng, copy dòng, paste
u, Ctrl+RUndo, Redo
/patternTìm kiếm; n/N tiến/lùi kết quả
:%s/old/new/gThay thế toàn bộ file

7. diff và Nano

Terminal – diff và Nano

$ diff file1.txt file2.txt

3c3

< This is old line

---

> This is new line

$ diff -u file1.txt file2.txt

# -u: unified format (dễ đọc hơn, dạng patch)

$ diff -r dir1/ dir2/

# So sánh đệ quy 2 thư mục

$ nano /etc/hosts

# Mở file với nano editor

# ^X = Ctrl+X: thoát | ^O: lưu | ^W: tìm kiếm | ^K: cắt dòng

Lab Thực Hành – Chapter 5

1

Phân tích file /etc/passwd với cut và awk

Terminal

$ cut -d: -f1,3,7 /etc/passwd | sort -t: -k2 -n | tail -5

chris:1001:/bin/bash

$ awk -F: '$3 >= 1000 && $3 != 65534 {print $1, "UID:", $3}' /etc/passwd

chris UID: 1001

$ awk -F: '{print $7}' /etc/passwd | sort | uniq -c | sort -rn

36 /sbin/nologin

4 /bin/bash

2

Tìm kiếm nâng cao với grep

Terminal

$ grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /etc/hosts

127.0.0.1 localhost

$ grep -rn "PermitRootLogin" /etc/ssh/

/etc/ssh/sshd_config:38:PermitRootLogin prohibit-password

$ grep -v "^#\|^$" /etc/ssh/sshd_config | wc -l

12

3

Xử lý Log File với sed và awk

Terminal

$ tail -100 /var/log/messages | grep -i "error\|warn" | sed 's/.*\(error\|warn\)/[\1]/'

$ awk '/error/{count++} END{print "Errors:", count}' /var/log/syslog

Errors: 5

$ awk '{print $4}' /var/log/nginx/access.log | cut -d: -f1 | sort | uniq -c

# Đếm request theo giờ

4

Thực hành Vim cơ bản

Terminal

$ vim /tmp/test_vim.txt

# Thực hiện các bước sau trong vim:

i # Vào insert mode

# Gõ: "Hello from Vim"

Esc # Về normal mode

o # Thêm dòng mới bên dưới

# Gõ: "Line 2"

Esc

:wq # Lưu và thoát

$ cat /tmp/test_vim.txt

Hello from Vim

Line 2

5

sed để sửa file cấu hình

Terminal

$ cp /etc/ssh/sshd_config /tmp/sshd_config.bak

$ sed -n '/^Port\|^#Port/p' /etc/ssh/sshd_config

#Port 22

$ sed 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config | grep "^Port"

Port 2222

$ diff /tmp/sshd_config.bak <(sed 's/#Port 22/Port 2222/' /etc/ssh/sshd_config)

6

Pipeline tổng hợp: Phân tích /etc/passwd

Terminal

$ echo "=== User Report ==="

$ echo "Total users: $(wc -l < /etc/passwd)"

$ echo "Login shells:"

$ grep -v "/nologin\|/false" /etc/passwd | cut -d: -f1 | sort

$ echo "Home dirs:"

$ awk -F: '$3>=1000{print $1": "$6}' /etc/passwd

chris: /home/chris

Câu Hỏi Ôn Tập – Chapter 5

1

Lệnh tail -f dùng để làm gì? Ứng dụng thực tế?

tail -f theo dõi file và hiển thị các dòng mới được thêm vào real-time (follow). Ứng dụng: theo dõi log server (tail -f /var/log/messages), debug ứng dụng, giám sát access log web (tail -f /var/log/nginx/access.log). Nhấn Ctrl+C để dừng.
2

Viết lệnh grep tìm tất cả dòng trong /var/log/messages chứa "error" nhưng không chứa "deprecated".

grep -i "error" /var/log/messages | grep -vi "deprecated". Hoặc với một lệnh: grep -iP "error(?!.*deprecated)" /var/log/messages. -i: case insensitive, -v: invert match (loại bỏ dòng khớp pattern).
3

Dùng sed để xóa tất cả dòng comment (#) và dòng trống trong một file cấu hình.

sed -e '/^#/d' -e '/^$/d' /etc/sshd_config. Hoặc: sed '/^[[:space:]]*#\|^[[:space:]]*$/d' file.conf. Dùng -i để sửa trực tiếp: sed -i '/^#/d; /^$/d' file.conf. Nên backup trước khi dùng -i.
4

Giải thích lệnh: awk -F: '$3>=1000{print $1}' /etc/passwd

-F: đặt delimiter là dấu ':'. Condition $3>=1000: chỉ xử lý dòng có trường thứ 3 (UID) >= 1000. {print $1}: in trường đầu tiên (username). Kết quả: liệt kê tất cả regular users (UID >= 1000, bỏ system accounts). Trên một số hệ thống có thể cần loại thêm UID 65534 (nobody).
5

3 cách thoát khỏi Vim. Khi nào dùng :q! thay vì :wq?

:wq – lưu và thoát; :x – tương tự :wq nhưng chỉ ghi khi có thay đổi; :q! – thoát không lưu (force). Dùng :q! khi: vô tình sửa nhầm file quan trọng và muốn hủy mọi thay đổi, hoặc khi chỉ xem file mà không có ý định sửa nhưng nhỡ tay gõ vào. ZZ trong Normal mode cũng tương đương :wq.
6

Sự khác biệt giữa less và more là gì?

more: chỉ cuộn xuống, không lên được, không tìm kiếm backward. less: cuộn được cả lên lẫn xuống, tìm kiếm /pattern và ?pattern (backward), nhảy đến dòng cụ thể (:N), xem nhiều file. less không load toàn bộ file vào memory nên nhanh hơn với file lớn. Khẩu hiệu: "less is more".
7

Viết pipeline đếm số lần mỗi địa chỉ IP xuất hiện trong /var/log/nginx/access.log.

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20. Giải thích: awk trích cột 1 (IP), sort sắp xếp (uniq cần input đã sort), uniq -c đếm, sort -rn sắp xếp giảm dần theo số, head -20 lấy top 20 IP nhiều nhất.
8

Làm thế nào để đếm tổng số ký tự, từ, và dòng trong một file?

wc file.txt hiển thị cả 3: dòng, từ, byte. wc -l chỉ đếm dòng, wc -w đếm từ, wc -c đếm byte, wc -m đếm ký tự (khác với -c khi có UTF-8). Ví dụ: wc -l /etc/passwd cho biết có bao nhiêu user accounts.