Cách sử dụng ngôn ngữ AWK để thao tác văn bản trong Linux
Các tiện ích Linux thường tuân theo triết lý thiết kế Unix. Các công cụ được khuyến khích nhỏ, sử dụng các file văn bản thuần túy cho đầu vào và kết quả , và hoạt động theo phương thức module . Do di sản này, ta có chức năng xử lý văn bản tuyệt vời với các công cụ như sed vàawk
. awk
vừa là ngôn ngữ lập trình vừa là trình xử lý văn bản mà bạn có thể sử dụng để thao tác dữ liệu văn bản theo những cách rất hữu ích. Trong hướng dẫn này, bạn sẽ khám phá cách sử dụng công cụ dòng lệnh awk
và cách sử dụng nó để xử lý văn bản.
Cú pháp cơ bản
Lệnh awk
được bao gồm theo mặc định trong tất cả các hệ thống Linux hiện đại, vì vậy bạn không cần phải cài đặt nó để bắt đầu sử dụng.
awk
hữu ích nhất khi xử lý các file văn bản được định dạng theo cách dễ đoán. Ví dụ, nó rất xuất sắc trong việc phân tích cú pháp và thao tác dữ liệu dạng bảng. Nó hoạt động trên cơ sở từng dòng và lặp qua toàn bộ file .
Theo mặc định, nó sử dụng khoảng trắng (dấu cách, tab, v.v.) để tách các trường. May mắn là nhiều file cấu hình trên hệ thống Linux của bạn sử dụng định dạng này.
Định dạng cơ bản của lệnh awk
là:
- awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse
Bạn có thể bỏ qua phần tìm kiếm hoặc phần hành động khỏi bất kỳ lệnh awk
nào. Theo mặc định, hành động được thực hiện nếu phần “hành động” không được cung cấp là “in”. Điều này chỉ đơn giản là in tất cả các dòng phù hợp.
Nếu phần tìm kiếm không được đưa ra, awk
thực hiện hành động được liệt kê trên mỗi dòng.
Nếu cả hai đều được đưa ra, awk
sử dụng phần tìm kiếm để quyết định xem dòng hiện tại có phản ánh mẫu hay không và sau đó thực hiện các hành động trên các kết quả phù hợp.
Ở dạng đơn giản nhất, bạn có thể sử dụng awk
like cat
để in tất cả các dòng của file văn bản ra màn hình.
Tạo một file tin favorite_food.txt
liệt kê các món ăn ưa thích của một group bạn bè:
- echo "carrot sandy
- wasabi luke
- sandwich brian
- salad ryan
- spaghetti jessica" > favorite_food.txt
Bây giờ sử dụng lệnh awk
để in file ra màn hình:
- awk '{print}' favorite_food.txt
Bạn sẽ thấy file được in ra màn hình:
Outputcarrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica
Điều này không hữu ích lắm. Ta hãy thử khả năng lọc tìm kiếm của awk
bằng cách tìm kiếm văn bản “sand” trong file :
- awk '/sand/' favorite_food.txt
Outputcarrot sandy sandwich brian
Như bạn thấy, awk
bây giờ chỉ in các dòng có ký tự "cát" trong đó.
Sử dụng biểu thức chính quy, bạn có thể nhắm đến các phần cụ thể của văn bản. Để chỉ hiển thị dòng bắt đầu bằng các chữ cái “sand”, hãy sử dụng biểu thức chính quy ^sand
:
- awk '/^sand/' favorite_food.txt
Lần này, chỉ có một dòng được hiển thị:
Outputsandwich brian
Tương tự, bạn có thể sử dụng phần hành động để chỉ định phần thông tin nào bạn muốn in. Ví dụ, để chỉ in cột đầu tiên, hãy sử dụng lệnh sau:
- awk '/^sand/ {print $1;}' favorite_food.txt
Outputsandwich
Bạn có thể tham chiếu mọi cột (được phân cách bằng khoảng trắng) bởi các biến được liên kết với số cột của chúng. Ví dụ: cột đầu tiên là $1
, cột thứ hai là $2
và bạn có thể tham chiếu toàn bộ dòng với $0
.
Biến nội bộ và định dạng mở rộng
Lệnh awk
sử dụng một số biến nội bộ để gán các phần thông tin nhất định khi nó xử lý một file .
Các biến nội bộ mà awk
sử dụng là:
- FILENAME : Tham chiếu đến file đầu vào hiện tại.
- FNR : Tham chiếu số lượng bản ghi hiện tại liên quan đến file đầu vào hiện tại. Ví dụ: nếu bạn có hai file đầu vào, điều này sẽ cho bạn biết số bản ghi của mỗi file thay vì tổng số.
- FS : Dấu phân tách trường hiện tại được sử dụng để biểu thị từng trường trong bản ghi. Theo mặc định, điều này được đặt thành khoảng trắng.
- NF : Số trường trong bản ghi hiện tại.
- NR : Số lượng bản ghi hiện tại.
- OFS : Dấu tách trường cho dữ liệu kết quả . Theo mặc định, điều này được đặt thành khoảng trắng.
- ORS : Dấu phân tách bản ghi cho dữ liệu kết quả . Theo mặc định, đây là một ký tự dòng mới.
- RS : Dấu phân tách bản ghi dùng để phân biệt các bản ghi riêng biệt trong file đầu vào. Theo mặc định, đây là một ký tự dòng mới.
Bạn có thể thay đổi giá trị của các biến này theo ý muốn để phù hợp với nhu cầu của file của bạn. Thông thường bạn làm điều này trong giai đoạn khởi tạo xử lý của bạn .
Điều này đưa ta đến một khái niệm quan trọng khác. Cú pháp awk
phức tạp hơn một chút so với những gì bạn đã sử dụng cho đến nay Ngoài ra còn có các khối BEGIN
và END
tùy chọn có thể chứa các lệnh để thực thi trước và sau khi xử lý file , tương ứng.
Điều này làm cho cú pháp mở rộng của ta trông giống như sau:
- awk 'BEGIN { action; }
- /search/ { action; }
- END { action; }' input_file
Các từ khóa BEGIN
và END
là tập hợp các điều kiện cụ thể, giống như các tham số tìm kiếm. Chúng khớp trước và sau khi tài liệu được xử lý.
Điều này nghĩa là bạn có thể thay đổi một số biến nội bộ trong phần BEGIN
. Ví dụ, /etc/passwd
file được giới hạn với dấu hai chấm ( :
) thay vì khoảng trắng.
Để in ra cột đầu tiên của file này, hãy thực hiện lệnh sau:
- sudo awk 'BEGIN { FS=":"; }
- { print $1; }' /etc/passwd
Outputroot daemon bin sys sync games man . . .
Bạn có thể sử dụng khối BEGIN
và END
để in thông tin về các trường bạn đang in. Sử dụng lệnh sau để chuyển đổi dữ liệu từ file thành một bảng, có khoảng cách phù hợp với các tab bằng \t
:
- sudo awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
- {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
- END { print "---------\nFile Complete" }' /etc/passwd
Bạn sẽ thấy kết quả này:
OutputUser UID GID Home Shell -------------- root 0 0 /root /bin/bash daemon 1 1 /usr/sbin /bin/sh bin 2 2 /bin /bin/sh sys 3 3 /dev /bin/sh sync 4 65534 /bin /bin/sync . . . --------- File Complete
Như bạn thấy, bạn có thể định dạng mọi thứ khá đẹp bằng cách tận dụng một số tính năng của awk
.
Mỗi phần mở rộng là tùy chọn. Trên thực tế, bản thân phần hành động chính là tùy chọn nếu phần khác được xác định. Ví dụ: bạn có thể làm những việc như sau:
- awk 'BEGIN { print "We can use awk like the echo command"; }'
Và bạn sẽ thấy kết quả này:
OutputWe can use awk like the echo command
Bây giờ ta hãy xem cách tìm kiếm văn bản trong các trường của kết quả .
Tìm kiếm trường và biểu thức tổng hợp
Trong một trong những ví dụ trước đó, bạn đã in dòng trong file favorite_food.txt
bắt đầu bằng “sand”. Điều này thật dễ dàng vì bạn đang tìm kiếm phần đầu của toàn bộ dòng.
Điều gì sẽ xảy ra nếu bạn muốn tìm hiểu xem liệu một mẫu tìm kiếm có khớp ở đầu một trường hay không?
Tạo một version mới của file tin favorite_food.txt
để thêm số thứ tự vào phía trước món ăn của mỗi người:
- echo "1 carrot sandy
- 2 wasabi luke
- 3 sandwich brian
- 4 salad ryan
- 5 spaghetti jessica" > favorite_food.txt
Nếu bạn muốn tìm tất cả các loại thực phẩm từ file này bắt đầu bằng “sa”, bạn có thể bắt đầu bằng cách thử thông tin như sau:
- awk '/sa/' favorite_food.txt
Điều này hiển thị tất cả các dòng có chứa "sa":
Output1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan
Ở đây, bạn đang kết hợp bất kỳ trường hợp nào của "sa" trong từ. Điều này kết thúc bao gồm những thứ như "wasabi" có hoa văn ở giữa hoặc "cát" không có trong cột bạn muốn. Trong trường hợp này, bạn chỉ quan tâm đến những từ bắt đầu bằng “sa” trong cột thứ hai .
Bạn có thể yêu cầu awk
chỉ khớp ở đầu cột thứ hai bằng cách sử dụng lệnh sau:
- awk '$2 ~ /^sa/' favorite_food.txt
Như bạn thấy , điều này cho phép ta chỉ tìm kiếm kết quả khớp ở đầu cột thứ hai.
Phần field_num ~
chỉ định rằng awk
chỉ nên chú ý đến cột thứ hai.
Output3 sandwich brian 4 salad ryan
Bạn có thể dễ dàng tìm kiếm những thứ không khớp bằng cách thêm dấu “!” ký tự trước dấu ngã (~). Lệnh này sẽ trả về tất cả các dòng không có thức ăn bắt đầu bằng “sa”:
- awk '$2 !~ /^sa/' favorite_food.txt
Output1 carrot sandy 2 wasabi luke 5 spaghetti jessica
Nếu sau này bạn quyết định rằng bạn chỉ quan tâm đến các dòng không bắt đầu bằng “sa” và số mục nhỏ hơn 5, bạn có thể sử dụng một biểu thức ghép như sau:
- awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt
Điều này giới thiệu một vài khái niệm mới. Đầu tiên là khả năng thêm các yêu cầu bổ sung để dòng phù hợp bằng cách sử dụng toán tử &&
. Sử dụng điều này, bạn có thể kết hợp một số điều kiện tùy ý để dòng phù hợp. Trong trường hợp này, bạn đang sử dụng toán tử này để thêm kiểm tra xem giá trị của cột đầu tiên có nhỏ hơn 5 hay không.
Bạn sẽ thấy kết quả này:
Output1 carrot sandy 2 wasabi luke
Bạn có thể sử dụng awk
để xử lý file , nhưng bạn cũng có thể làm việc với kết quả của các chương trình khác.
Xử lý kết quả từ các chương trình khác
Bạn có thể sử dụng lệnh awk
để phân tích cú pháp kết quả của các chương trình khác thay vì chỉ định tên file . Ví dụ: bạn có thể sử dụng awk
để phân tích cú pháp địa chỉ IPv4 từ lệnh ip
.
Lệnh ip a
hiển thị địa chỉ IP, địa chỉ quảng bá và các thông tin khác về tất cả các network interface trên máy của bạn. Để hiển thị thông tin cho giao diện được gọi là eth0
, hãy sử dụng lệnh sau:
- ip a s eth0
Bạn sẽ thấy các kết quả sau:
Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
Bạn có thể sử dụng awk
để nhắm đến dòng inet
và sau đó chỉ in ra địa chỉ IP:
- ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'
Cờ -F
yêu cầu awk
phân tách bằng dấu gạch chéo hoặc dấu cách bằng biểu thức chính quy [\/ ]+
. Điều này chia dòng inet 172.17.0.11/16
thành các trường riêng biệt. Địa chỉ IP nằm trong trường thứ ba vì khoảng trắng ở đầu dòng cũng được tính là một trường, vì bạn được phân cách bằng dấu cách cũng như dấu gạch chéo. Lưu ý awk
coi các khoảng trắng liên tiếp như một khoảng trắng trong trường hợp này.
Đầu ra hiển thị địa chỉ IP:
Output172.17.0.11
Bạn sẽ tìm thấy nhiều nơi mà bạn có thể sử dụng awk
để tìm kiếm hoặc phân tích cú pháp kết quả của các lệnh khác.
Kết luận
Bây giờ, bạn đã hiểu cơ bản về cách bạn có thể sử dụng lệnh awk
để thao tác, định dạng và in có chọn lọc các file văn bản và stream văn bản. Tuy nhiên, Awk là một chủ đề lớn hơn nhiều và thực sự là một ngôn ngữ lập trình hoàn chỉnh với phép gán biến, cấu trúc điều khiển, hàm tích hợp và hơn thế nữa. Bạn có thể sử dụng nó trong các tập lệnh của riêng mình để định dạng văn bản theo cách tin cậy .
Để tìm hiểu thêm về awk
, bạn có thể đọc cuốn sách domain công cộng miễn phí của những người tạo ra nó, cuốn sách này đi sâu vào chi tiết hơn.
Các tin liên quan
Cách thiết lập Nền tảng Cloud IDE server mã trên Ubuntu 20.042020-05-20
Khái niệm cơ bản về việc sử dụng Sed Stream Editor để thao tác văn bản trong Linux
2020-05-19
Sedan trung gian: Thao tác các dòng văn bản trong môi trường Linux
2020-05-19
Cách cài đặt Linux, Nginx, MySQL, PHP ( LEMP) trên Ubuntu 20.04 [Quickstart]
2020-05-14
Cách thiết lập Nền tảng Cloud IDE server mã trên Ubuntu 18.04
2020-05-13
Cách tạo server Minecraft trên Ubuntu 18.04
2020-05-07
Cách tạo server Minecraft trên Ubuntu 20.04
2020-05-07
Cách cài đặt Linux, Apache, MySQL, PHP (LAMP) trên Ubuntu 20.04 [Quickstart]
2020-05-07
Cách cài đặt Linux, Apache, MySQL, PHP (LAMP) trên Ubuntu 20.04
2020-04-29
Cách cài đặt Linux, Nginx, MySQL, PHP ( LEMP) trên Ubuntu 20.04
2020-04-29