NỘI DUNG

Hosting tốc độ cao Vietnix - tốc độ tải trang trung bình dưới 1 giây
VPS siêu tốc Vietnix - trải nghiệm mượt mà, ổn định
29/05/2024
Lượt xem

Hướng dẫn cách sử dụng lệnh awk trong Linux

29/05/2024
16 phút đọc
Lượt xem

Đánh giá

5/5 - (184 bình chọn)

Lệnh awk trong Linux là một công cụ mạnh mẽ và linh hoạt dành cho việc xử lý và phân tích dữ liệu dạng văn bản. Được đặt tên theo ba nhà phát triển ban đầu của nó: Alfred Aho, Peter Weinberger và Brian Kernighan, awk giúp người dùng dễ dàng duyệt, tìm kiếm và thao tác các dòng và cột trong tệp văn bản. Trong bài hướng dẫn này, hãy cùng Vietnix sẽ tìm hiểu cách sử dụng lệnh awk trong Linux để thực hiện các nhiệm vụ cho hệ thống.

Lệnh awk trong Linux hoạt động như thế nào?

HIện nay có một số cách triển khai khác nhau của awk. VIetnix sẽ sử dụng triển khai GNU của awk, được gọi là gawk. Trên hầu hết các hệ thống Linux, trình thông dịch awk chỉ là một liên kết tượng trưng (symlink) đến gawk.

Record và Field

Awk có thể xử ký các file và luồng dữ liệu dạng văn bản. Dữ liệu đầu vào được chia thành các bản ghi (record) và trường (field). Awk hoạt động trên từng bản ghi cho đến khi kết thúc đầu vào. Các bản ghi được phân tách bằng ký tự phân tách bản ghi (record separator – RS), trong đó ký tự mặc định là newline. Khi đó mỗi dòng trong dữ liệu văn bản sẽ được xem là một bản ghi. Các ký tự tách bản ghi có thể được cài đặt bằng biến RS.

Bản ghi chứa các trường và được phân chia bởi ký tự tách trường (field separator). Theo mặc định thì ký tự này là khoảng trắng, trong đó gồm một hay nhiều ký tự tab, space hoặc ký tự newline. Các trường trong một bản ghi được tham chiếu bằng ký hiệu $, theo sau là mã số trường và bắt đầu bằng số 1. Vì vậy, trường đầu tiên được biểu diễn là $1, trường thứ hai là $2,… Trường cuối cùng có tham chiếu đặc biệt là $NF, và toàn bộ bản ghi được tham chiếu bằng mã $0.

Ví dụ về cách tham chiếu bản ghi và trường:

tmpfs      788M  1.8M  786M   1% /run/lock  /dev/sda1  234G  191G   31G  87% / |-------|  |--|  |--|   |--| |-| |--------|     $1       $2    $3     $4   $5  $6 ($NF) --> fields |-----------------------------------------|                      $0                     --> record

Chương trình awk

Để xử lý văn bản bằng awk, bạn có thể viết một chương trình chứa các quy tắc và hàm tự định nghĩa để chỉ dẫn cho lệnh thực hiện. Mỗi quy tắc chứa một mẫu và cặp hành động (action). Các quy tắc được phân tách nhau bằng ký tự newline hoặc dấu “;”. Thường thì một chương trình awk sẽ có dạng như sau:

pattern { action } pattern { action } ...

Khi awk xử lý dữ liệu, nếu mẫu khớp với bản ghi thì awk sẽ thực hiện action được chỉ định trong bản ghi này. Nếu quy tắc không có mẫu thì toàn bộ bản ghi sẽ được khớp.

Một hành awk action được định nghĩa bởi các câu lệnh đặt trong cặp dấu ngoặc ngọn “{…}”. Một action có thể có nhiều hơn một câu lệnh, các câu lệnh được phân tách nhau bởi ký tự newline hoặc dấu ;. Nếu quy tắc không có action nào thì awk sẽ in toàn bộ bản ghi theo mặc định.

Awk hỗ trợ rất nhiều loại câu lệnh khác nhau, bao gồm cả biểu thức, điều kiện, câu lệnh input/output,… Các lệnh awk phổ biến nhất gồm có:

  • exit – Dừng quá trình thực thi toàn bộ chương trình và thoát.
  • next – Dừng thực thi bản ghi hiện tại và chuyển sang bản ghi tiếp theo trong dữ liệu đầu vào.
  • print – In ra các bản ghi, trường, biến và văn bản.
  • printf – Cho phép người dùng kiểm soát định dạng output tốt hơn, tương tự như C và bash printf.

Khi viết các chương trình awk, mọi thứ đằng sau dấu # cho đến cuối dòng đều được xem là một comment. Các dòng văn bản dài có thể được ngắt xuống dòng bằng ký tự \.

Thực thi chương trình awk

Một chương trình awk có thể chạy theo nhiều phương pháp khác nhau. Nếu chương trình tương đối ngắn và đơn giản, bạn có thể truyền trực tiếp vào trình phiên dịch của awk trong command-line:

awk 'program' input-file...

Khi chạy chương trình trên command-line, bạn nên đặt trong cặp dấu nháy đơn (‘…’) để shell không phiên dịch chương trình.

Nếu cần chạy một chương trình lớn và phức tạp thì bạn nền đặt chương trình này vào một file rồi dùng option -f để truyền file vào lệnh awk trong Linux:

awk -f program-file input-file...

Trong bài viết này, các ví dụ minh họa sẽ xoay quanh file teams.txt có nội dung như sau:

Bucks Milwaukee    60 22 0.732  Raptors Toronto    58 24 0.707  76ers Philadelphia 51 31 0.622 Celtics Boston     49 33 0.598 Pacers Indiana     48 34 0.585

Mẫu awk

Mẫu trong awk có nhiệm vụ kiểm soát xem action có nên được thực hiện hay không. Awk hỗ trợ nhiều kiểu khớp mẫu khác nhau như: biểu thức chính quy, biểu thức quan hệ, mẫu biểu thức đặc biệt,…

Nếu quy tắc không định nghĩa mẫu nào thì từng bản ghi sẽ được khớp. Giả sử bạn có một quy tắc chỉ chứa duy nhất một action:

awk '{ print $3 }' teams.txt

Bây giờ chương trình sẽ in ra trường thứ ba cảu mỗi bản ghi:

60 58 51 49 48

Mẫu biểu thức chính quy

Biểu thức chính quy (regular expression/regex) là một mẫu có khả năng khớp một tập hợp các chuỗi. Một mẫu regex của awk được đặt trong cặp dấu //:

/regex pattern/ { action }

Ví dụ bạn muốn hiển thị trường đầu tiên của từng bản ghi có chứa chuỗi 0.5:

awk '/0.5/ { print $1 }' teams.txt

Output:

Celtics Pacers

Mẫu có thể là bất kỳ kiểu regex nào. Bạn cũng có thể in ra trường đầu tiên nếu bản ghi bắt đầu bằng hai chữ số trở lên:

awk '/^[0-9][0-9]/ { print $1 }' teams.txt

Output:

76ers

Mẫu biểu thức quan hệ

Các mẫu biểu thức quan hệ thường được dùng để khớp nội dung của một trường hay biến nhất định. Theo mặc định, các mẫu regex được khớp dựa trên bản ghi. Để khớp regex theo trường thì bạn cần chỉ định trường và dùng toán tử so sánh contain (~).

Giả sử bạn cần in trường đầu tiên của môi bản ghi, trong đó trường thứ hai chứa chuỗi “ia“:

awk '$2 ~ /ia/ { print $1 }' teams.txt

Output:

76ers Pacers

Ngược lại, nếu muốn khớp các trường không chứa mẫu thì bạn có thể dùng toán tử !~:

awk '$2 !~ /ia/ { print $1 }' teams.txt

Output:

Bucks Raptors Celtics

Ngoài ra bạn cũng có thể so sánh các chuỗi và chữ số với nhau, với các toán tử như: lớn hơn, bằng, nhỏ hơn,…

Ví dụ sau cần in ra trường đầu tiên của mọi bản ghi có trường giá trị trường thứ ba lớn hơn 50:

awk '$3 > 50 { print $1 }' teams.txt

Output:

Bucks Raptors 76ers

Mẫu theo khoảng

Mẫu theo khoảng (range pattern) gồm hai mẫu phân tách nhau bởi dấu phẩy:

pattern1, pattern2

Mẫu này sẽ khớp mọi bản ghi bắt đầu từ pattern1 đến pattern2. Lấy ví dụ, câu lệnh dưới đây sẽ in ra trường đầu tiên của mọi bản ghi, bắt đầu từ bản ghi chứa chuỗi “Raptors” cho đến bản ghi chứa chuỗi “Celtics”:

awk '/Raptors/,/Celtics/ { print $1 }' teams.txt

Output:

Raptors 76ers Celtics

Ngoài ra, mẫu cũng có thể là các biểu thức quan hệ. Ví dụ lệnh dưới đây có nhiệm vụ in ra mọi bản ghi, bắt đầu từ bản ghi có giá trị của trường thứ tư là 32, đến bản ghi có trường thứ tư bằng 33:

awk '$4 == 31, $4 == 33 { print $0 }' teams.txt

Output:

76ers Philadelphia 51 31 0.622 Celtics Boston     49 33 0.598

Các mẫu biểu thức đặc biệt

Lệnh awk trong Linux cũng cung cấp một số mẫu đặc biệt như sau:

  • BEGIN – Dùng để thực hiện các action trước khi xử lý bản ghi.
  • END – Dùng để thực hiện action sau khi xử lý bản ghi.

Mẫu BEGIN thường dùng để đặt biến và mẫu END có thể dùng để xử lý dữ liệu từ các bản ghi.

Ví dụ đoạn code sau cần in ra chuỗi “Start Processing”, sau đó in trường thứ ba của mỗi bản ghi rồi kết thúc bằng chuỗi “End Processing”:

awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt

Output:

Start Processing
60
58
51
49
48
End Processing.

Nếu một chương trình chỉ có mẫu BEGIN thì câu lệnh chỉ thực hiện các action mà không xử lý inout. Ngược lại, nếu chương trình chỉ có mẫu END thì lệnh sẽ xử lý input trước khi thực hiện các action.

Kết hợp các mẫu trong awk

Awk cho phép kết hợp hai hay nhiều mẫu khác nhau bằng toán tử logic AND (&&) và OR (||).

Ví dụ dùng toán tử && để in ra trường đầu tiên của các bản ghi có giá trị của trường thứ ba lớn hơn 50, đồng thời giá trị của trường thứ tư cũng lớn hơn 30:

awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt

Output:

Bucks Raptors

Các biến có sẵn trong awk

Awk cung cấp một số biến có sẵn chứa các thông tin hữu ích, đồng thời cho phép kiểm soát cách xử lý dữ liệu của chương trình. Một số biến phổ biến trong awk gồm có:

  • NF – Số lượng trường có trong bản ghi.
  • NR – Số lượng bản ghi hiện tại.
  • FILENAME – Tên của file input đang được xử lý.
  • FS – Ký tự phân tách trường (field separator).
  • RS – Ký tự phân tách bản ghi (record separator).
  • OFS – Ký tự phân tách trường đầu ra (output field separator).
  • ORS – Ký tự phân tách bản ghi đầu ra (output record separator).

Ví dụ bạn cần in tên file và số lượng dòng (bản ghi) trong đó:

awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt

Output:

File teams.txt contains 5 lines.

Các biến trong awk có thể được đặt ở bất kỳ dòng nào trong chương trình. Để định nghĩa một biến cho toàn bộ chương trình, bạn có thể đặt trong mẫu BEGIN.

Thay đổi ký tự phân tách trường và bản ghi

Ký tự phân tách mặc định của trường là tab hoặc space. Bạn có thể thay đổi thông qua biến FS. Giả sử muốn đặt thành dấu .:

File teams.txt contains 5 lines.

Output:

Bucks Milwaukee    60 22 0 Raptors Toronto    58 24 0 76ers Philadelphia 51 31 0 Celtics Boston     49 33 0 Pacers Indiana     48 34 0

Ký tự phân tách trường cũng có thể được đặt thành nhiều ký tự:

awk 'BEGIN { FS = ".." } { print $1 }' teams.txt

Khi chạy các lệnh awk chỉ có một dòng trong command-line, bạn có thể dùng option -F để đổi ký tự phân tách trường:

awk -F "." '{ print $1 }' teams.txt

Theo mặc định thì ký tự phân tách bản ghi là newline, và cũng có thể được đổi qua biến RS.

Tương tự, giả sử bạn muốn đổi thành ký tự .:

awk -F "." '{ print $1 }' teams.txt

Output:

Bucks Milwaukee    60 22 0 732  Raptors Toronto    58 24 0 707  76ers Philadelphia 51 31 0 622 Celtics Boston     49 33 0 598 Pacers Indiana     48 34 0 585

Các action trong awk

Các action có thể được đặt trong cặp dấu {} và thực thi khi mẫu được khớp. Một action có thể có 0 hay nhiều câu lệnh. Các câu lệnh được thực hiện lần lượt và phân tách nhau bởi ký tự newline hoặc dấu ;.

Một số loại câu lệnh action trong awk:

  • Biểu thức, chẳng hạn như gán biến, toán tử số học,…
  • Câu lệnh điều khiển (if, for, while, switch,…)
  • Lệnh output (print, printf)
  • Câu lệnh ghép
  • Câu lệnh input
  • Câu lệnh xóa

Lệnh print chắc chắn là một trong những lệnh awk phổ biến nhất, dùng để hiển thị output của văn bản, bản ghi, trường và biến.

Khi in nhiều giá trị khác nhau, bạn cần phân tách nhau bằng dấu phẩy. Ví dụ:

awk '{ print $1, $3, $5 }' teams.txt

Output (mặc định thì các item được tách nhau bởi một khoảng trắng):

Bucks 60 0.732 Raptors 58 0.707 76ers 51 0.622 Celtics 49 0.598 Pacers 48 0.585

Nếu không dùng dấu phẩy thì sẽ không có khoảng trắng giữa các item:

awk '{ print $1 $3 $5 }' teams.txt

Output:

Bucks600.732 Raptors580.707 76ers510.622 Celtics490.598 Pacers480.585

Nếu dùng lệnh print mà không có tham số thì option mặc định sẽ là print $0, tức là in ra bản ghi hiện tại.

Để in một đoạn văn bản, bạn có thể đặt trong cặp dấu ngoặc kép:

awk '{ print "The first field:", $1}' teams.txt

Output:

The first field: Bucks The first field: Raptors The first field: 76ers The first field: Celtics The first field: Pacers

Bạn cũng có thể in các ký tự đặc biệt như newline:

awk 'BEGIN { print "First line\nSecond line\nThird line" }'

Output:

First line Second line Third line

Lệnh printf cho phép kiểm soát định dạng output tốt hơn. Giả sử bạn cần đánh chỉ số dòng khi in ra màn hình:

awk '{ printf "%3d. %s\n", NR, $0 }' teams.txt

Output:

  1. Bucks Milwaukee    60 22 0.732    2. Raptors Toronto    58 24 0.707    3. 76ers Philadelphia 51 31 0.622   4. Celtics Boston     49 33 0.598   5. Pacers Indiana     48 34 0.585

Khi viết các chương trình dài, bạn có thể tạo một file chương trình awk riêng như sau:

BEGIN {    i = 1   while (i < 6) {      print "Square of", i, "is", i*i;      ++i    }  }

Chạy chương trình bằng cách truyền tên file vào trình phiên dịch của awk:

awk -f prg.awk

Sử dụng biến Shell trong chương trình awk

Nếu đang dùng lệnh awk trong shell script thì có thể bạn sẽ cần chuyển một biến shell cho chương trình awk. Khi đó, bạn có thể đặt chương trình trong cặp dấu nháy kép (thay vì nháy đơn) rồi thay tên biến trong chương trình. Tuy nhiên, việc này lại vô tình khiến chương trình awk trở nên phức tạp hơn.

Mặt khác, bạn có thể dùng các biến shell trong chương trình awk bằng cách gán các biến này vào một biến awk. Ví dụ:

awk -v n="$num" 'BEGIN {print n}'

Output:

51

Lời kết

Awk là một trong những công cụ xử lý văn bản mạnh mẽ nhất trong Linux. Bài viết này đã cung cấp những kiến thức và cách sử dụng lệnh awk trong Linux cơ bản nhất. Bạn đọc có thể khảo thêm tài liệu hướng dẫn của awk để hiểu rõ hơn về công cụ này. Chúc các bạn thành công!

THEO DÕI VÀ CẬP NHẬT CHỦ ĐỀ BẠN QUAN TÂM

Đăng ký ngay để nhận những thông tin mới nhất từ blog của chúng tôi. Đừng bỏ lỡ cơ hội truy cập kiến thức và tin tức hàng ngày

Chọn chủ đề :

Hưng Nguyễn

Co-Founder
tại

Kết nối với mình qua

Kết nối với mình qua

Theo dõi
Thông báo của
guest
0 Comments
Phản hồi nội tuyến
Xem tất cả bình luận

Tăng tốc độ website - Nâng tầm giá trị thương hiệu

Tăng tốc tải trang

95 điểm

Nâng cao trải nghiệm người dùng

Tăng 8% tỷ lệ chuyển đổi

Thúc đẩy SEO, Google Ads hiệu quả

Tăng tốc ngay

SẢN PHẨM NỔI BẬT

7 NGÀY DÙNG THỬ HOSTING

NẮM BẮT CƠ HỘI, THÀNH CÔNG DẪN LỐI

Cùng trải nghiệm dịch vụ hosting tốc độ cao được hơn 100,000 khách hàng sử dụng

ĐĂNG KÝ NHẬN TÀI LIỆU THÀNH CÔNG
Cảm ơn bạn đã đăng ký nhận tài liệu mới nhất từ Vietnix!
ĐÓNG

ĐĂNG KÝ DÙNG THỬ HOSTING

7 NGÀY MIỄN PHÍ

ĐĂNG KÝ DÙNG THỬ HOSTING

7 NGÀY MIỄN PHÍ

XÁC NHẬN ĐĂNG KÝ DÙNG THỬ THÀNH CÔNG
Cảm ơn bạn đã đăng ký thông tin thành công. Đội ngũ CSKH sẽ liên hệ trực tiếp để kích hoạt dịch vụ cho bạn nhanh nhất!
ĐÓNG