Câu 1Phần thân của BEGIN { ... } chạy khi nào?
awk — Tổng hợp và Báo cáo
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?