Thứ Tư, 29 tháng 10, 2014

[CLI] Awk - phân tích text file và scaning pattern.

Bài viết thực hiện trên:
thanhnguyen@thanhnguyen:~$ lsb_release -r
Release: 12.04
AWK là gì?
Awk là một Programming language, nhằm mục đích xử lý các text file và scaning pattern ( quét mẫu). Ta có thể kết hợp awk với shell script hoặc sử dụng trực tiếp với command lines.

Awk làm việc như thế nào?
Awk phân tích mỗi dòng thành các trường (fields). Thông thường, các trường được phân cách với nhau bởi các spaces (tuy nhiên, bạn có thể thay đổi điều này với option -F).
$0 là toàn bộ các trường (cả dòng).
$1 là trường thứ nhất.
$2 là trường thứ 2.

Cú pháp.
Dạng cú pháp cơ bản của Awk là:
mẫu_1 { câu lệnh_1 };
mẫu_2 { câu lệnh_2 };
............

Một số câu lệnh với awk thường dùng:

1. In một file ra màn hình.
awk '{ print }' filename
hoặc:
awk '{ print $0 }' filename
2. In một trường bất kì của một dòng:
echo $line |awk '{ print $n }'
ví dụ:
$ echo một hai | awk '{print $1}' # sẽ cho ra:
một
3. Đối chiếu với một mẫu.
ví dụ hiển thị tất cả dòng từ file log của Apache nếu HTTP error code bằng 500 ( trường thứ 9 ($9) là logs status error code cho mỗi yêu cầu http ):
awk '$9 == 500 { print $0}' /var/log/httpd/access.log
hoặc:
cat /var/log/httpd/access.log | awk '$9 == 500 { print $0}'
4. In ra các dòng có từ aaa hoặc bbb trong một file.
awk '/aaa|bbb/' filename
5. Bạn cũng có thể dùng các các mệnh đề điều kiện với awk.
Ví dụ, kiểm tra một field thỏa mãn một điều kiện với if clause trước khi in nó ra.
awk '{if ($3 < 1980) print $3, " ",$5,$6,$7,$8}' filename
Một ví dụ khác:

trong ví dụ trên, chúng ta đã thấy được rằng, nếu muốn in ra nhiều trường cùng một lúc, bạn có thể ngăn cách chúng bởi các dấu ',' và khi in ra, chúng tương đương với 1 space. Khi không được ngăn cách với ',' chúng sẽ in liền sát nhau.
Nếu bạn muốn tăng khoảng cách, hoặc đặt các kí tự như ',', ..in ra giữa các trường, hãy đặt vào giữa chúng các space, hoặc các kí tự đó vào trong " " như trong ví dụ sau:


6. In ra nội dung bất kì của một file.
# In ra số dòng của một file.
awk 'END { print NR}' filename
# In ra dòng cuối của file.
awk 'END { print NR," ", $0}' filename
# In ra dòng n bất kì trong một file.
awk '{if (NR==n) print $0}' filename
awk "NR==n{print;exit}" filename

Trong ví dụ trên, ta có thể dễ dàng nhận ra rằng NR chỉ thứ tự của các dòng.

Để tìm hiểu thêm:
man awk
Bài viết chỉ nêu ra một vài ví dụ cơ bản với awk, rất mong nhận được sự đóng góp của các bạn để bổ xung thêm các trường hợp còn thiếu, giúp bài viết được hoàn thiện và hữu ích. Thanks all.

                                                                                        --- Thanks for reading ---




2 nhận xét:

  1. > cat /var/log/httpd/access.log | awk '$9 == 500 { print $0}'

    xem vd này xong người dùng dễ có tư tưởng cat file ra rồi mới dùng awk, đây là một bad practice.

    > 5. Bạn cũng có thể dùng các các mệnh đề điều kiện với awk.

    làm thế noà để các field cách nhau bằng dấu , ?

    Trả lờiXóa
  2. thanks for your comment. i fixed it

    Trả lờiXóa