Cách sử dụng lệnh awk trên Linux

Trên Linux,awk là một động lực thao tác văn bản dòng lệnh, cũng như một ngôn ngữ kịch bản mạnh mẽ. Dưới đây là phần giới thiệu về một số tính năng thú vị nhất của nó.

Làm thế nào awk có tên của nó

Cácawk 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 của 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

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ó 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

Có lẽ chúng tôi không cần tất cả 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 in hành động để in trường đầu tiên.

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

ai | awk '{print $ 1}'

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 nhập như sau để in thời gian người đó đã đăng nhập (trường bốn):

ai | awk '{in $ 1, $ 4}'

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

Chúng tôi muốnawk để 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 bọc trong cửa sổ dòng lệnh, 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

Chúng tôi không biết rằng "sự đơn giản". là trường thứ 18 trong dòng văn bản và chúng tôi không quan tâm. Những gì chúng tôi biết là đó là trường cuối cùng và chúng tôi có thể sử dụng $ NF để nhận đượ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ừngày lệnh hơi đặc biệt vì thời gian được xếp 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:

ngày
ngày tháng | awk '{in $ 2, $ 3, $ 6}'

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 ({}):

ngày tháng | awk 'OFS = "/" {print $ 2, $ 3, $ 6}'
ngày tháng | awk 'OFS = "-" {print $ 2, $ 3, $ 6}'

Quy tắc BEGIN và END

A BẮT ĐẦU 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 hiện trước khi awk thậm chí đọc bất kỳ văn bản nào. An KẾT THÚC 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 BẮT ĐẦUKẾT THÚC và chúng sẽ thực thi theo thứ tự.

Ví dụ của chúng tôi về một BẮT ĐẦU 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

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

Chúng tôi có thể sử dụng kỹ thuật tương tự với lệnh mà chúng tôi đã 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:

ai | awk 'BEGIN {print "Phiên hoạt động"} {print $ 1, $ 4}'

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 tá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) tùy chọn để nói awk để sử dụng dấu hai chấm (:) làm dấu phân cách. Chúng tôi gõ những điều 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

Đầ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).

Thêm mẫu

Nếu tất cả 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. Bởi vì số ID người dùng 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 để dựa trên thông tin đó.

Chúng tôi nhập nội dung 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

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 BẮT ĐẦU 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 "Tài khoản Người dùng \ n -------------"} $ 3> = 1000 {print $ 1, $ 6}' / etc / passwd

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) 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

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 kết quả tương tự nếu không có in vì hành động mặc định sẽ in toàn bộ dòng văn bản. Tuy nhiên, để rõ ràng, thường hữu ích khi nói rõ ràng. Khi bạn xem qua tập lệnh hoặc tệp lịch sử của mình, bạn sẽ rất vui vì đã để lại manh mối cho chính mình.

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ái đó tốt hơn! Bây giờ, chúng tôi chỉ thấy hướng dẫn lắp chính hãng. Để 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

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 có kết quả.

Để trình bày 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ụ: đây là một cách phức tạp để yêu cầu căn bậc hai của 25:

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

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 tôi 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.

Các BẮT ĐẦU quy tắc thực hiện các bước chuẩn bị, trong khiKẾT THÚC 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 tập lệnh 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ó 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ạ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 {# đặt dấu phân cách trường đầu vào và đầu ra FS = ":" OFS = ":" # zero the account counter account = 0} {# đặt trường 2 thành không $ 2 = "" # print toàn bộ dòng in $ 0 # count tài khoản tài khoản khác ++} HẾT {# in kết quả in tài khoản "tài khoản. \ n"}

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

chmod + x omit.awk

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 tinawk 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

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

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.

awk không đứng cho lúng túng

awk không chịu đựng sự khó xử; nó tượng trưng cho sự sang trọng. Nó được mô tả như một bộ lọc xử lý và một người viết báo cáo. Chính xác hơn, đó là cả hai công việc này, hay đúng hơn là một công cụ bạn có thể sử dụng cho cả hai tác vụ này. Chỉ trong vài dòng,awk đạt được những gì yêu cầu mã hóa rộng rãi bằng một ngôn ngữ truyền thống.

Sức mạnh đó được khai thác bởi khái niệm đơn giản về các quy tắc chứa các mẫu, chọn văn bản để xử lý và các hành động xác định quá trình xử lý.


$config[zx-auto] not found$config[zx-overlay] not found