Lệnh awk trên Linux là gì? Ứng dụng và cách sử dụng của nó?

0

Trên Linux, awk là command-line. Thế nhưng làm sao để có thể sử dụng chúng?

Lịch sử của awk?

Các awk Lệnh được đặt tên bằng cách sử dụng tên viết tắt của ba người đã viết phiên bản gốc vào năm 1977: Alfred Aho, Peter Weinberger và Brian Kernighan. Ba người đàn ông này đến từ phòng thí nghiệm huyền thoại AT&T Bell Laboratories Unix. Với sự đóng góp của nhiều người khác kể từ đó, awk đã tiếp tục phát triển.

Đó là một ngôn ngữ kịch bản đầy đủ, cũng như một bộ công cụ thao tác văn bản hoàn chỉnh cho dòng lệnh. Nếu bài viết này kích thích sự thèm ăn của bạn, bạn có thể kiểm tra mọi chi tiết về awk và chức năng của nó.

Quy tắc, Mẫu và Hành động của awk

awk hoạt động trên các chương trình có chứa các quy tắc bao gồm các mẫu và hành động. Hành động được thực hiện trên văn bản phù hợp với mẫu. Các mẫu được đặt trong dấu ngoặc nhọn ({}). Cùng với nhau, một khuôn mẫu và một hành động tạo thành một quy tắc. Toàn bộ awk chương trình được đặt trong dấu nháy đơn (').

Chúng ta hãy xem xét loại đơn giản nhất của awk chương trình. Nó không có khuôn mẫu, vì vậy nó khớp với mọi dòng văn bản được đưa vào nó. Điều này có nghĩa là hành động được thực hiện trên mọi dòng. Chúng tôi sẽ sử dụng nó trên đầu ra từ who chỉ huy.

Đây là đầu ra tiêu chuẩn từ who:

who

Lệnh "ai" trong cửa sổ dòng lệnh.

Có lẽ chúng tôi không cần tất cả những thông tin đó, mà thay vào đó, chúng tôi chỉ muốn xem tên trên các tài khoản. Chúng tôi có thể chuyển đầu ra từ who thành awk, và sau đó nói awk để chỉ in trường đầu tiên.

Theo mặc định, awk coi một trường là một chuỗi ký tự được bao quanh bởi khoảng trắng, đầu dòng hoặc cuối dòng. Các trường được xác định bằng ký hiệu đô la ($) và một số. Vì thế, $1 đại diện cho trường đầu tiên, mà chúng tôi sẽ sử dụng với print hành động để in trường đầu tiên.

Chúng tôi gõ như sau:

who | awk '{print $1}'

Các "ai |  awk '{print $ 1}'" lệnh trong cửa sổ đầu cuối.

awk in trường đầu tiên và loại bỏ phần còn lại của dòng.

Chúng tôi có thể in bao nhiêu trường tùy thích. Nếu chúng ta thêm dấu phẩy làm dấu phân cách, awk in một khoảng trắng giữa mỗi trường.

Chúng tôi gõ như sau để in thời gian người đó đã đăng nhập (trường bốn):

who | awk '{print $1,$4}'

Các "ai |  awk '{in $ 1, $ 4}'" lệnh trong cửa sổ đầu cuối.

Có một vài số nhận dạng trường đặc biệt. Chúng đại diện cho toàn bộ dòng văn bản và trường cuối cùng trong dòng văn bản:

  • $ 0: Đại diện cho toàn bộ dòng văn bản.
  • $ 1: Đại diện cho trường đầu tiên.
  • $ 2: Đại diện cho trường thứ hai.
  • $ 7: Đại diện cho trường thứ bảy.
  • $ 45: Đại diện cho trường thứ 45.
  • $ NF: Viết tắt của “số trường” và đại diện cho trường cuối cùng.

Chúng tôi sẽ nhập nội dung sau để hiển thị một tệp văn bản nhỏ chứa một trích dẫn ngắn được gán cho Dennis Ritchie:

cat dennis_ritchie.txt

Lệnh "cat dennis_ritchie.txt" trong cửa sổ dòng lệnh.

Chúng tôi muốn awk để in trường đầu tiên, thứ hai và cuối cùng của câu trích dẫn. Lưu ý rằng mặc dù nó được bao quanh trong cửa sổ đầu cuối, nhưng nó chỉ là một dòng văn bản.

Chúng tôi gõ lệnh sau:

awk '{print $1,$2,$NF}' dennis_ritchie.txt

Các "awk '{print $ 1, $ 2, $ NF}' dennis_ritchie.txt" lệnh trong cửa sổ đầu cuối.

Những gì chúng tôi biết đó là trường cuối cùng và chúng tôi có thể sử dụng $NF để có được giá trị của nó. Dấu chấm chỉ được coi là một ký tự khác trong cơ thể của lĩnh vực này.

Thêm dấu phân tách trường đầu ra

Bạn cũng có thể nói awk để in một ký tự cụ thể giữa các trường thay vì ký tự khoảng trắng mặc định. Đầu ra mặc định từ date lệnh hơi đặc biệt vì thời gian được tô điểm ngay giữa nó. Tuy nhiên, chúng ta có thể gõ như sau và sử dụng awk để trích xuất các trường chúng tôi muốn:

date
date | awk '{print $2,$3,$6}'

Các "ngày" và "ngày tháng |  awk '{in $ 2, $ 3, $ 6}'" lệnh trong cửa sổ đầu cuối.

Chúng tôi sẽ sử dụng OFS (dấu phân tách trường đầu ra) để đặt dấu phân cách giữa tháng, ngày và năm. Lưu ý rằng bên dưới chúng tôi đặt lệnh trong dấu ngoặc kép ('), không phải dấu ngoặc nhọn ({}):

date | awk 'OFS="https://www.howtogeek.com/" {print$2,$3,$6}'
date | awk 'OFS="-" {print$2,$3,$6}'

Các "ngày tháng |  awk 'OFS ="/" {in $ 2, $ 3, $ 6} '" và "ngày tháng |  awk 'OFS ="-" {in $ 2, $ 3, $ 6} '" lệnh trong cửa sổ đầu cuối.

Quy tắc BEGIN và END

A BEGIN quy tắc được thực thi một lần trước khi bất kỳ quá trình xử lý văn bản nào bắt đầu. Trên thực tế, nó được thực thi trước khi awk thậm chí đọc bất kỳ văn bản nào. An END quy tắc được thực thi sau khi tất cả quá trình xử lý hoàn tất. Bạn có thể có nhiều BEGINEND và chúng sẽ thực hiện theo thứ tự.

Ví dụ của chúng tôi về một BEGIN quy tắc, chúng tôi sẽ in toàn bộ trích dẫn từ dennis_ritchie.txt tệp chúng tôi đã sử dụng trước đây với tiêu đề ở trên nó.

Để làm như vậy, chúng ta gõ lệnh sau:

awk 'BEGIN {print "Dennis Ritchie"} {print $0}' dennis_ritchie.txt

Các "awk 'BEGIN {in "Dennis Ritchie"} {print $ 0} 'dennis_ritchie.txt" lệnh trong cửa sổ đầu cuối.

Lưu ý BEGIN rule có một tập hợp các hành động của riêng nó nằm trong một tập hợp các dấu ngoặc nhọn ({}).

Chúng ta có thể sử dụng kỹ thuật tương tự với lệnh mà chúng ta đã sử dụng trước đây để chuyển đầu ra từ who thành awk. Để làm như vậy, chúng tôi nhập như sau:

who | awk 'BEGIN {print "Active Sessions"} {print $1,$4}'

Các "ai |  awk 'BEGIN {in "Phiên hoạt động"} {in $ 1, $ 4} '" lệnh trong cửa sổ đầu cuối.

Dấu phân tách trường nhập

Nếu bạn muốn awk để làm việc với văn bản không sử dụng khoảng trắng để phân tách các trường, bạn phải cho nó biết ký tự nào mà văn bản sử dụng làm dấu phân cách trường. Ví dụ, /etc/passwd tệp sử dụng dấu hai chấm (:) để tách các trường.

Chúng tôi sẽ sử dụng tệp đó và -F (chuỗi phân tách) để nói awk để sử dụng dấu hai chấm (:) làm dấu phân cách. Chúng tôi gõ sau đây để nói awk để in tên của tài khoản người dùng và thư mục chính:

awk -F: '{print $1,$6}' /etc/passwd

Các "awk -F: '{print $ 1, $ 6}' / etc / passwd" lệnh trong cửa sổ đầu cuối.

Đầu ra chứa tên của tài khoản người dùng (hoặc ứng dụng hoặc tên daemon) và thư mục chính (hoặc vị trí của ứng dụng).

Đầu ra từ "awk -F: '{print $ 1, $ 6}' / etc / passwd" lệnh trong cửa sổ đầu cuối.

Thêm mẫu

Nếu những gì chúng tôi quan tâm là tài khoản người dùng thông thường, chúng tôi có thể bao gồm một mẫu với hành động in của mình để lọc ra tất cả các mục nhập khác. Vì số User ID bằng hoặc lớn hơn 1.000, chúng tôi có thể dựa trên bộ lọc của mình để lọc thông tin đó.

Chúng tôi nhập dòng lệnh sau để thực hiện hành động in của chúng tôi chỉ khi trường thứ ba ($3) chứa giá trị 1.000 trở lên:

awk -F: '$3 >= 1000 {print $1,$6}' /etc/passwd

Các "awk -F: '$ 3> = 1000 {print $ 1, $ 6}' / etc / passwd" lệnh trong cửa sổ đầu cuối.

Mẫu phải ngay trước hành động được liên kết với nó.

Chúng ta có thể sử dụng BEGIN quy tắc cung cấp tiêu đề cho báo cáo nhỏ của chúng tôi. Chúng tôi gõ như sau, sử dụng (n) ký hiệu để chèn một ký tự dòng mới vào chuỗi tiêu đề:

awk -F: 'BEGIN {print "User Accountsn-------------"} $3 >= 1000 {print $1,$6}' /etc/passwd

Các "awk -F: 'BEGIN {in "Tài khoản Người dùng  n -------------"} $ 3> = 1000 {print $ 1, $ 6} '/ etc / passwd" lệnh trong cửa sổ đầu cuối.

Các mẫu là biểu thức chính quy đầy đủ và chúng là một trong những vinh quang của awk.

Giả sử chúng tôi muốn xem các số nhận dạng duy nhất (UUID) phổ biến của các hệ thống tệp được gắn kết. Nếu chúng ta tìm kiếm thông qua /etc/fstab tệp cho các lần xuất hiện của chuỗi “UUID”, nó phải trả lại thông tin đó cho chúng tôi.

Chúng tôi sử dụng mẫu tìm kiếm “/ UUID /” trong lệnh của chúng tôi:

awk '/UUID/ {print $0}' /etc/fstab

Các "awk '/ UUID / {print $ 0}' / etc / fstab" lệnh trong cửa sổ đầu cuối.

Nó tìm tất cả các lần xuất hiện của “UUID” và in các dòng đó. Chúng tôi thực sự sẽ nhận được cùng một kết quả nếu không có print vì hành động mặc định sẽ in toàn bộ dòng văn bản.

Dòng đầu tiên được tìm thấy là một dòng nhận xét và mặc dù chuỗi “UUID” nằm ở giữa, awk vẫn tìm thấy nó. Chúng tôi có thể điều chỉnh biểu thức chính quy và cho biết awk để chỉ xử lý các dòng bắt đầu bằng “UUID”. Để làm như vậy, chúng tôi nhập dòng sau bao gồm mã thông báo đầu dòng (^):

awk '/^UUID/ {print $0}' /etc/fstab

Các "awk '/ ^ UUID / {print $ 0}' / etc / fstab" lệnh trong cửa sổ đầu cuối.

Bây giờ, chúng tôi chỉ thấy hướng dẫn lắp. Để tinh chỉnh đầu ra hơn nữa, chúng tôi nhập nội dung sau và hạn chế hiển thị ở trường đầu tiên:

awk '/^UUID/ {print $1}' /etc/fstab

Các "awk '/ ^ UUID / {print $ 1}' / etc / fstab" lệnh trong cửa sổ đầu cuối.

Nếu chúng tôi có nhiều hệ thống tệp được gắn trên máy này, chúng tôi sẽ nhận được một bảng gọn gàng về các UUID của chúng.

Chức năng tích hợp sẵn

awk có nhiều chức năng mà bạn có thể gọi và sử dụng trong các chương trình của riêng mình, cả từ dòng lệnh và tập lệnh. Nếu bạn đào một ít, bạn sẽ thấy nó rất hiệu quả.

Để chứng minh kỹ thuật chung để gọi một hàm, chúng ta sẽ xem xét một số kỹ thuật số. Ví dụ, sau đây in ra căn bậc hai của 625:

awk 'BEGIN { print sqrt(625)}'

Lệnh này in ra arctang của 0 (không) và -1 (xảy ra là hằng số toán học, pi):

awk 'BEGIN {print atan2(0, -1)}'

Trong lệnh sau, chúng tôi sửa đổi kết quả của atan2() chức năng trước khi chúng tôi in nó:

awk 'BEGIN {print atan2(0, -1)*100}'

Các hàm có thể chấp nhận các biểu thức dưới dạng tham số. Ví dụ:

awk 'BEGIN { print sqrt((2+3)*5)}'

Các "awk 'BEGIN {print sqrt (625)}'" lệnh trong cửa sổ đầu cuối.

Tập lệnh awk

Nếu dòng lệnh của bạn trở nên phức tạp hoặc bạn phát triển một quy trình mà bạn biết rằng bạn sẽ muốn sử dụng lại, bạn có thể chuyển awk lệnh thành một tập lệnh.

Trong tập lệnh ví dụ của chúng tôi, chúng tôi sẽ thực hiện tất cả những điều sau:

  • Cho shell biết tệp thực thi nào được sử dụng để chạy tập lệnh.
  • Chuẩn bị awk sử dụng FS biến phân tách trường để đọc văn bản đầu vào với các trường được phân tách bằng dấu hai chấm (:).
  • Sử dụng OFS dấu tách trường đầu ra để nói awk để sử dụng dấu hai chấm (:) để tách các trường trong đầu ra.
  • Đặt bộ đếm thành 0 (không).
  • Đặt trường thứ hai của mỗi dòng văn bản thành giá trị trống (nó luôn là “x”, vì vậy chúng ta không cần phải nhìn thấy nó).
  • In dòng với trường thứ hai đã sửa đổi.
  • Tăng bộ đếm.
  • In giá trị của bộ đếm.

Kịch bản của chúng tôi được hiển thị bên dưới.

Ví dụ về tập lệnh awk trong trình soạn thảo.

Các BEGIN quy tắc thực hiện các bước chuẩn bị, trong khi END quy tắc hiển thị giá trị bộ đếm. Quy tắc giữa (không có tên hoặc mẫu để phù hợp với mọi dòng) sửa đổi trường thứ hai, in dòng và tăng bộ đếm.

Dòng đầu tiên của script cho shell biết tệp thực thi nào được sử dụng (awk, trong ví dụ của chúng tôi) để chạy tập lệnh. Nó cũng vượt qua -f (tên tệp) tùy chọn để awk, thông báo cho nó rằng văn bản mà nó sẽ xử lý sẽ đến từ một tệp. Chúng tôi sẽ chuyển tên tệp cho tập lệnh khi chúng tôi chạy nó.

Chúng tôi đã bao gồm tập lệnh bên dưới dưới dạng văn bản để bạn có thể cắt và dán:

#!/usr/bin/awk -f

BEGIN {
  # set the input and output field separators
  FS=":"
  OFS=":"
  # zero the accounts counter
  accounts=0
}
{
  # set field 2 to nothing
  $2=""
  # print the entire line
  print $0
  # count another account
  accounts++
}
END {
  # print the results
  print accounts " accounts.n"
}

Lưu nó trong một tệp có tên omit.awk. Để làm cho tập lệnh có thể thực thi được, chúng tôi gõ như sau bằng cách sử dụng chmod:

chmod +x omit.awk

Lệnh "chmod + x omit.awk" trong cửa sổ dòng lệnh.

Bây giờ, chúng tôi sẽ chạy nó và vượt qua /etc/passwd tệp vào tập lệnh. Đây là tập tin awk sẽ xử lý cho chúng tôi, sử dụng các quy tắc trong tập lệnh:

./omit.awk /etc/passwd

Lệnh "./omit.awk / etc / passwd" trong cửa sổ dòng lệnh.

Tệp được xử lý và từng dòng được hiển thị, như hình dưới đây.

Xuất từ ​​"./omit.awk / etc / passwd" trong cửa sổ dòng lệnh.

Các mục nhập “x” trong trường thứ hai đã bị xóa, nhưng lưu ý rằng các dấu phân cách trường vẫn còn. Các dòng được đếm và tổng số được đưa ra ở cuối đầu ra.

Hy vọng rằng bài viết này đã giúp ích được cho bạn! Followeek chúc bạn một ngày mới tốt lành.

Leave a Reply

Your email address will not be published. Required fields are marked *