Câu 1Phần thân của BEGIN { ... } chạy khi nào?
awk — Tổng hợp và báo cáo
Bài viết này là một phần của Khóa học Linux, giúp bạn thành thạo từ đầu những kỹ năng Linux thực tiễn, từ các lệnh cơ bản đến lập trình shell script.
Thực hành awk: thứ tự chạy của BEGIN { } và END { }, cách dùng s += $1 để tích lũy cột 1 thành tổng, và đếm bằng NR hoặc { c++ } để tạo báo cáo tổng hợp — minh họa và thực hành trên terminal trong trình duyệt.
Chạy Trước và Sau — BEGIN và END
awk xử lý từng dòng theo thứ tự, nhưng bạn có thể đặt những việc muốn chạy một lần trước và sau vào BEGIN { ... } và END { ... }. BEGIN chạy một lần trước khi đọc dòng đầu tiên, và END chạy một lần sau khi đọc xong tất cả các dòng. Dùng chúng để in tiêu đề ở đầu hoặc in tóm tắt ở cuối cùng.
BEGIN chạy một lần trước khi xử lý, phần thân chạy theo từng dòng, và END chạy một lần sau.| Cú pháp | Ý nghĩa |
|---|---|
BEGIN { ... } | Chạy một lần trước khi đọc dòng đầu tiên |
{ ... } | Phần thân chạy lặp lại, từng dòng một |
END { ... } | Chạy một lần sau khi đọc xong tất cả các dòng |
s += $1 | Liên tục cộng cột 1 vào biến s (tổng tích lũy) |
NR | Số dòng đã đọc cho đến nay (tổng số dòng ở cuối) |
{ c++ } END { print c } | Tăng c theo từng dòng và in bộ đếm ở cuối |
printf 'start\nmiddle\nend\n' > lines.txt # create 3 lines of material
awk 'BEGIN { print "--- report ---" } { print $0 } END { print "rows:", NR }' lines.txt
# a header up front, rows: 3 at the end
Tổng và Đếm — s += $1 và NR
Trong awk bạn có thể dùng biến mà không cần khai báo, và các số được cộng trực tiếp. Viết { s += $1 } trong phần thân sẽ liên tục cộng cột đầu tiên của mỗi dòng vào biến s, và END { print s } in tổng ở cuối. Để đếm số dòng, bạn có thể in NR (số dòng đã đọc) trực tiếp trong END, hoặc tăng bộ đếm bằng { c++ } và in bằng END { print c }. Nhờ vậy bạn có thể tạo các báo cáo tổng hợp như tổng doanh thu hay số lượng bản ghi.
s += $1 cộng cột 1 từng dòng, và END in tổng là 60.printf '120 mon\n80 tue\n200 wed\n' > sales.txt # create 3 lines with numbers
awk '{ s += $1 } END { print "total:", s }' sales.txt # total: 400
awk 'END { print "days:", NR }' sales.txt # days: 3
Đếm bằng Bộ đếm — { c++ } END { print c }
NR đếm tất cả các dòng, nhưng khi bạn muốn chỉ đếm các dòng thỏa điều kiện, hãy dùng bộ đếm trong phần thân. { c++ } tăng biến c lên 1 cho mỗi dòng được đọc, và END { print c } in số đếm đó. Thêm mẫu như /pat/{ c++ } sẽ chỉ đếm các dòng chứa chuỗi cụ thể.
/pass/{ c++ } tăng c chỉ trên các dòng khớp, và END in số đếm là 2.| Cú pháp | Ý nghĩa |
|---|---|
{ c++ } | Tăng biến c lên 1 cho mỗi dòng được đọc |
/pattern/{ c++ } | Tăng c chỉ trên các dòng chứa pattern |
END { print c } | In số đếm c một lần ở cuối |
printf 'ok pay\nng pay\nok ship\n' > log.txt # create 3 lines with a status
awk '/ok/{ c++ } END { print "ok count:", c }' log.txt # count lines containing ok -> 2
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2awk '{ s += $1 } END { print s }' f hiển thị gì?
Câu 3Khi bạn in NR trong khối END, điều gì xuất hiện?