Tìm hiểu Awk cơ bản
Bài đăng này đã không được cập nhật trong 7 năm
Nếu bạn đang dành toàn bộ hoặc phần lớn thời gian của mình để làm việc với UNIX/Linux, có những công cụ sẽ giúp bạn gia tăng tốc độ làm việc và trở nên hiệu quả hơn. Một trong số đó là Awk. Trong bài viết này, chúng ta sẽ cùng tìm hiểu về cách sử dụng Awk cơ bản thông qua các ví dụ cụ thể.
Giới thiệu
Awk là một ngôn ngữ lập trình hỗ trợ thao tác dễ dàng đối với kiểu dữ liệu có cấu trúc và tạo ra những kết quả được định dạng. Nó được đặt tên bằng cách viết tắt các chữ cái đầu tiên của các tác giả: Aho, Weinberger và Kernighan.
Awk thường được sử dụng cho việc tìm kiếm và xử lý text. Nó sẽ tìm kiếm một hoặc nhiều file để xem xem trong các file đó có dòng nào bao gồm những pattern
(khuôn mẫu) cho trước hay không, sau đó thực hiện những action
(hành động) tương ứng.
Một số đặc điểm nổi bật của Awk:
- nó xem 1 file text giống như bảng dữ liệu, bao gồm các bản ghi và các trường
- tương tự những ngôn ngữ lập trình phổ biến, Awk cũng có những khái niệm như biến, điều kiện, vòng lặp
- Awk có những toán tử số học và toán tử thao tác chuỗi
Câu lệnh được viết với Awk sẽ nhận đầu vào là một file hoặc một input có dạng chuẩn, rồi tạo ra output theo chuẩn của nó. Awk chỉ làm việc với các file text.
Cú pháp cơ bản của câu lệnh được viết với Awk sẽ như sau:
awk '/search pattern 1/ {Actions}
/search pattern 2/ {Actions}' file
Giải thích:
search pattern
là một biểu thức chính quyActions
là những câu lệnh sẽ được thực hiệnfile
: file đầu vào Awk sẽ chấp nhận một vài kiểupattern
vàaction
.
Cách thức hoạt động
- Chương trình được viết với Awk đọc file đầu vào theo từng dòng một
- Đối với mỗi dòng, nó sẽ so khớp dòng ấy lần lượt với các
pattern
, nếu khớp thì sẽ thực hiệnaction
tương ứng - Nếu không có
pattern
nào được so khớp thì sẽ không cóaction
nào được thực hiện - Trong cú pháp cơ bản khi làm việc với Awk, hoặc
search pattern
có thể vắng mặt, hoặcaction
có thể vắng mặt, nhưng không được khuyết cả 2 - Nếu không có
search pattern
, Awk sẽ thực hiệnaction
đã cho đối với mỗi dòng của dữ liệu đầu vào - Nếu
action
vắng mặt, Awk sẽ mặc định in ra tất cả những dòng khớp vớipattern
đã cho - Chương trình có cặp ngoặc nhọn không chứa
action
nào sẽ không thực hiện gì cả, kể cả thao tác mặc định (in ra tất cả các dòng) - Mỗi câu lệnh trong phần
action
được phân tách nhau bởi dấu chấm phẩy
Tiếp theo, chúng ta sẽ tạo ra file employee.txt
để sử dụng trong các ví dụ sau đó:
➜ ~ cat employee.txt
100 Thomas Manager Sales $5,000
200 Jason Developer Technology $5,500
300 Sanjay Sysadmin Technology $7,000
400 Nisha Manager Marketing $9,500
500 Randy DBA Technology $6,000
Nội dung của file này trông giống như một bảng dữ liệu bao gồm 5 trường, có thể đặt tên một cách hợp lý là: id, name, designation, department, salary.
1. Hành động mặc định
Theo mặc định, chương trình được viết với Awk sẽ in ra từng dòng của file đầu vào:
➜ ~ awk '{print;}' employee.txt
100 Thomas Manager Sales $5,000
200 Jason Developer Technology $5,500
300 Sanjay Sysadmin Technology $7,000
400 Nisha Manager Marketing $9,500
500 Randy DBA Technology $6,000
Trong ví dụ này, không có sự xuất hiện của phần pattern
, do đó lệnh print
được áp dụng cho toàn bộ các dòng.
2. In ra những dòng có chứa xâu mẫu
➜ ~ awk '/Thomas/
quote> /Nisha/' employee.txt
100 Thomas Manager Sales $5,000
400 Nisha Manager Marketing $9,500
Ví dụ này sẽ in ra toàn bộ những dòng có chứa cụm từ Thomas hoặc Nisha. Chương trình bao gồm 2 pattern
. Awk sẽ chấp nhận số lượng tùy ý các pattern
, nhưng mỗi một cặp pattern
- action
phải được viết ở một dòng riêng biệt.
3. Chỉ in ra những trường nhất định
Awk được thiết kế bao gồm một vài biến dựng sẵn. Đối với mỗi bản ghi, tức là một dòng, theo mặc định nó chia bản ghi này ra thành từng phần ngăn cách nhau bởi các khoảng trắng và lưu trong các biến có dạng $n. Nếu một dòng có 4 từ, các từ ấy sẽ được lưu trong các biến $1
, $2
, $3
và $4
. $0
đại diện cho toàn bộ dòng. NF
là biến dựng sẵn lưu giữ giá trị tổng số trường của một bản ghi.
➜ ~ awk '{print $2, $5;}' employee.txt
Thomas $5,000
Jason $5,500
Sanjay $7,000
Nisha $9,500
Randy $6,000
➜ ~ awk '{print $2, $NF;}' employee.txt
Thomas $5,000
Jason $5,500
Sanjay $7,000
Nisha $9,500
Randy $6,000
Ở ví dụ trên, $2 và $5 đại diện cho trường Name và Salary. Chúng ta cũng có thể lấy ra giá trị của trường Salary bằng cách sử dụng biến $NF.
4. Hành động khởi tạo và kết thúc
Awk có 2 pattern
đặc biệt được chỉ ra bởi các từ khóa BEGIN
và END
. Cú pháp của Awk khi sử dụng với 2 pattern
này như sau:
BEGIN {Actions}
{Action} # Action for every line in a file
END {Actions}
Ở đây, nội dung viết sau dấu #
là cú pháp comment code khi làm việc với Awk.
Những hành động được chỉ định trong phần BEGIN
sẽ được thực thi trước khi đọc dòng đầu tiên từ dữ liệu nhập vào. Những hành động được sử dụng với từ khóa END
sẽ có tác dụng ngược lại. Ví dụ:
➜ ~ awk 'BEGIN {print "Name\tDesignation\tDepartment\tSalary";}
quote> {print $2,"t",$3,"\t",$4,"\t",$NF;}
quote> END {print "Report Generated\n-----------------";}' employee.txt
Name Designation Department Salary
Thomas t Manager Sales $5,000
Jason t Developer Technology $5,500
Sanjay t Sysadmin Technology $7,000
Nisha t Manager Marketing $9,500
Randy t DBA Technology $6,000
Report Generated
-----------------
Chương trình này đã có thêm dòng tiêu đề và dòng kết thúc cho kết quả đầu ra.
5. Phép so sánh
➜ ~ awk '$1 > 200' employee.txt
300 Sanjay Sysadmin Technology $7,000
400 Nisha Manager Marketing $9,500
500 Randy DBA Technology $6,000
Đối với file ví dụ employee.txt có cấu trúc như một bảng dữ liệu, trường đầu tiên là id
, tương ứng với biến $1. Do đó, nếu $1 lớn hơn 200 thì chương trình sẽ thực hiện hành động mặc định là in ra màn hình nội dung cả dòng.
6. Cú pháp điều kiện
Giả sử chúng ta muốn in ra danh sách những nhân viên thuộc phòng kỹ thuật. Với ví dụ này, tên phòng ban, bộ phận làm việc tương ứng với trường thứ 4, do đó cần kiểm tra điều kiện nếu biến $4 so khớp với xâu ký tự Technology thì sẽ in ra dòng tương ứng.
➜ ~ awk '$4 ~ /Technology/' employee.txt
200 Jason Developer Technology $5,500
300 Sanjay Sysadmin Technology $7,000
500 Randy DBA Technology $6,000
Toán tử ~
(thuật ngữ tiếng Anh tương ứng là tilde
) được dùng để so sánh giá trị của một trường với một biểu thức chính quy. Nếu kết quả là khớp, dòng dữ liệu đó sẽ được in ra màn hình.
7. Tính toán số học
Chương trình dưới đây sẽ kiểm tra xem phòng ban có phải là phòng kỹ thuật hay không, nếu có thì giá trị của biến count
được tăng lên 1 đơn vị. Biến này được khởi tạo giá trị ban đầu bằng 0 với từ khóa BEGIN
.
➜ ~ awk 'BEGIN {count = 0;}
quote> $4 ~ /Technology/ {count++;}
quote> END {print "Number of employees in Technology Dept=", count;}' employee.txt
Number of employees in Technology Dept= 3
Kết thúc chương trình, giá trị của biến count
được in ra chính là số lượng nhân viên thuộc phòng kỹ thuật.
Còn rất nhiều những khả năng tuyệt vời khác mà chúng ta có thể thực hiện được với Awk, một công cụ hữu ích, mạnh mẽ khi làm việc trên môi trường UNIX/Linux. Hi vọng bài viết này sẽ là bước gợi mở để các bạn tiếp tục tìm hiểu vấn đề sâu hơn.
Tài liệu tham khảo
Awk Introduction Tutorial – 7 Awk Print Examples How To Use the AWK language to Manipulate Text in Linux
All rights reserved