Lý thuyết

Sau một vài lần sử dụng 'awk' command để thao tác dữ liệu và tạo báo cáo khá hiệu quả. Nay mình viết lại một số tip nhỏ, tuy nhỏ nhưng khá hiệu quả trong các việc như quét và xử lý mẫu. Nó tìm kiếm một hoặc nhiều tệp để xem liệu chúng có chưa các dòng khớp với mẫu đã chỉ định hay không và sau đó thực hiện các dòng lệnh liên quan.
Một số action như:

  • Quét một tệp theo các dòng
  • Chia từng dòng đầu vào thành các trường
  • So sánh dòng/trường đầu vào với mẫu
  • Thực hiện hành động trên các dòng

Hữu ích nhất đối với:

  • Chuyển đổi tệp dữ liệu
  • Tạo báo cáo theo định dạng

Cú pháp

awk option program inputFile 

Với option có thể là:
-f : file chứa kịch bản lệnh xử lý
-F (hay FS) : input phân tách (field separator)

Thực hành

Lý thuyết thế đủ rồi, giờ bắt đầu đi vào thực hành qua các ví dụ thôi.

Using Variables

Khi thực hiện xử lý, awk sẽ gán dữ liệu tìm thấy cho một số biến, $0 cho dòng, $1 là trường thứ nhất trong dòng, $n là trường thứ n trong dòng. Ký tự khoảng trắng như dấu space hay tab là dấu phân tách mặc định giữa các field nếu có.

[email protected]:~/Desktop/awk$ cat myfile 
this is a test
this is the second test
this is the third test
this is the fourth test

[email protected]:~/Desktop/awk$ awk '{print $1}' myfile 
this
this
this
this

Thỉnh thoảng dấu phân tách không phải khoảng trắng thì ta chỉ định dấu phân tách bằng cách sử dụng lựa chọn -F

[email protected]:~/Desktop/awk$ awk '{print}' /etc/passwd
duongvantien:x:1000:1000:DuongVanTien,,,:/home/duongvantien:/bin/bash
mysql:x:121:129:MySQL Server,,,:/nonexistent:/bin/false
guest-gndm9y:x:999:998:Guest:/tmp/guest-gndm9y:/bin/bash
postgres:x:122:130:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
mongodb:x:123:65534::/home/mongodb:/bin/false

[email protected]:~/Desktop/awk$ awk -F: '{print $1}' /etc/passwd
duongvantien
mysql
guest-gndm9y
postgres
mongodb

Using Multiple Commands

Dùng dấu chấm phảy giữa các lệnh

[email protected]:~/Desktop/awk$ echo "Hello Tom" | awk '{$2="Adam"; print $0}'
Hello Adam

Reading The Script From a File

[email protected]:~/Desktop/awk$ cat testFile_01 
{
   text = $1 "------ home at -----" $6
   print text  
}

[email protected]:~/Desktop/awk$ awk -F: -f testFile_01 /etc/passwd
duongvantien------ home at -----/home/duongvantien
mysql------ home at -----/nonexistent
guest-gndm9y------ home at -----/tmp/guest-gndm9y
postgres------ home at -----/var/lib/postgresql
mongodb------ home at -----/home/mongodb

Dấu phân tách là dấu hai chấm ":" bởi từ khóa -F

Awk Preprocessing (tiền xử lý), Postprocessing (hậu xử lý)

Có thể thêm tiền xử lý hoặc hậu xử lý, ví dụ như thêm title, header hoặc footer .... bằng cách sử dụng từ khóa BEGIN và END

[email protected]:~/Desktop/awk$ awk 'BEGIN {print "[hearder] The File Contents:"} {print $0} END {print "[footer] end file"}' myfile 
[hearder] The File Contents:
this is a test
this is the second test
this is the third test
this is the fourth test
[footer] end file

hoặc một ví dụ khác đoạn xử lý được viết trong file như sau

[email protected]:~/Desktop/awk$ cat myscript 
BEGIN {
   print "Users and thier corresponding home"
   print "UserName \t HomePath"
   print "___________ \t __________"
   FS=":"
}
{
   print $1 " \t " $6
}
END {
   print "The end"
}

[email protected]:~/Desktop/awk$ awk -f myscript  /etc/passwd
Users and thier corresponding home
UserName 	 HomePath
___________ 	 __________
duongvantien 	 /home/duongvantien
mysql 	 /nonexistent
guest-gndm9y 	 /tmp/guest-gndm9y
postgres 	 /var/lib/postgresql
mongodb 	 /home/mongodb
The end

Vì trong khối lệnh của BEGIN ta đã thiết lập FS=":" rồi nếu không cũng có thể đặt bên ngoài như sau

[email protected]:~/Desktop/awk$ awk -F: -f myscript  /etc/passwd

Print the lines which matches with the given pattern

In ra tất cả những dòng match với "the"

[email protected]:~/Desktop/awk$ awk '/the/ {print $0}' myfile 
this is the second test
this is the third test
this is the fourth test

Một số Built In Variables In Awk

- NR : in ra số thự tự dòng match với xử lý

[email protected]:~/Desktop/awk$ awk '/the/ {print NR, $0}' myfile 
2 this is the second test
3 this is the third test
4 this is the fourth test

hay sử dụng để lấy từ dòng x đến dòng y như sau

[email protected]:~/Desktop/awk$ awk 'NR==2, NR==3 {print NR, $0}' myfile 
2 this is the second test
3 this is the third test

- NF : hiển thị field cuối cùng

[email protected]:~/Desktop/awk$ awk '{print $1, $4, $NF}' myfile 
this test test
this second test
this third test
this fourth test

To find the length of the longest line present in the file

  • Tìm dòng có số ký tự dài nhất trong file
[email protected]:~/Desktop/awk$ awk '{if(length($0) > max) max=length($0)} END {print max}' myfile 
23

To count the lines in a file

  • Đếm số dòng trong file
[email protected]:~/Desktop/awk$ awk 'END {print NR}' myfile 
4

Printing lines with more than 14 characters

[email protected]:~/Desktop/awk$ awk 'length($0) > 14' myfile 
this is the second test
this is the third test
this is the fourth test

To find/check for any string in any column

[email protected]:~/Desktop/awk$ awk '{if($4 == "second") print $0}' myfile 
this is the second test

Trên đây là một số ví dụ sử dụng awk khá hữu ích, mọi người có thể xem link tham khảo bài viết gốc bên dưới: https://likegeeks.com/awk-command/ https://www.geeksforgeeks.org/awk-command-unixlinux-examples/