Sự khác biệt chính xác giữa awk và cắt với grep là gì? [đóng cửa]


30

Chúng tôi biết rằng chúng tôi có thể nhận được cột thứ hai của dòng chúng tôi muốn từ một tệp bằng hai kỹ thuật sau:

awk '/WORD/ { print $2 }' filename

hoặc là

grep WORD filename| cut -f 2 -d ' '

Câu hỏi của tôi là:

  • Sự khác biệt giữa hai lệnh trên là gì?
  • Cái nào có hiệu suất tốt nhất?
  • Những lợi thế của việc sử dụng awkhơn sử dụng cut, và ngược lại là gì?
  • Những lựa chọn nào awkcho chúng ta hơn cutvà ngược lại?

echo filenamehay cat filename?
Avinash Raj

@AvinashRaj xin lỗi đã được chỉnh sửa
Networker

Câu trả lời:


35

Sự khác biệt nổi bật nhất giữa hai dòng của bạn sẽ phụ thuộc vào đầu vào. cutlấy một ký tự -dlàm dấu phân cách trường (mặc định là TAB) và mỗi lần xuất hiện của ký tự đó sẽ bắt đầu một trường mới. awktuy nhiên, linh hoạt hơn. Dấu phân cách nằm trong FSbiến và có thể là một chuỗi rỗng (mỗi ký tự đầu vào tạo một trường riêng), một ký tự đơn hoặc biểu thức chính quy. Trường hợp đặc biệt của một ký tự khoảng trắng (mặc định) có nghĩa là phân chia trên bất kỳ chuỗi khoảng trắng nào. Ngoài ra, awkngăn chặn khoảng trắng hàng đầu theo mặc định.

Vui lòng so sánh:

$ echo "abc def" | cut -f 2 -d ' '
def
$ echo "abc    def" | cut -f 2 -d ' '

$ echo " abc def" | cut -f 2 -d ' '
abc


$ echo "abc def" | awk '{ print $2 }'
def
$ echo "abc    def" | awk '{ print $2 }'
def
$ echo " abc def" | awk '{ print $2 }'
def

Ở đây, awkphân chia theo chuỗi các không gian giữa abcdeftrong khi đó cutlấy mọi không gian làm dấu phân cách.

Những gì bạn mất sẽ phụ thuộc vào những gì bạn muốn đạt được. Mặt khác, tôi mong đợi cutsẽ nhanh hơn vì nó là một công cụ đơn mục đích nhỏ hơn trong khi awkcó ngôn ngữ lập trình riêng.


rằng những gì tôi muốn là một câu trả lời, cảm ơn tôi sẽ đánh dấu câu hỏi như đã trả lời @Dubu
Networker

1
cutcó khả năng nhanh hơn Awk một mình , nhưng không chắc là nó grep ... | cutsẽ nhanh hơn Awk thuần túy.
tự đại diện

8

Nói chung, một công cụ càng chuyên dụng thì càng nhanh. Vì vậy, trong hầu hết các trường hợp, bạn có thể mong đợi cutgrepnhanh hơn sed, và sednhanh hơn awk. Nếu bạn đang kết hợp các đường ống dài hơn của các công cụ đơn giản hơn với một lần gọi một công cụ phức tạp hơn, thì không có quy tắc nào. Điều này chỉ quan trọng với đầu vào lớn (giả sử, hàng triệu dòng); đối với đầu vào ngắn, bạn sẽ không thấy bất kỳ sự khác biệt.

Ưu điểm của các công cụ phức tạp hơn tất nhiên là chúng có thể làm được nhiều thứ hơn.

Lệnh của bạn sử dụng mèo không cần thiết. Thay vào đó, hãy sử dụng chuyển hướng (đặc biệt nếu bạn lo lắng về tốc độ, mặc dù có lẽ bạn không nên lo lắng về tốc độ cho đến khi bạn chạy điểm chuẩn¹).

<fileName awk '/WORD/ { print $2 }'
<fileName grep WORD | cut -f 2 -d ' '

Các lệnh này gần như tương đương. Sự khác biệt là:

  • awk và grep có các cú pháp regrec khác nhau . Awk và grep -Ecó các cú pháp regrec gần như giống hệt nhau (các biểu thức chính quy mở rộng).
  • cut -d ' 'coi mỗi nhân vật không gian riêng lẻ là một dấu phân cách. Dấu phân cách mặc định của Awk là bất kỳ chuỗi khoảng trắng nào, có thể là nhiều khoảng trắng, một tab, v.v. Bạn không thể sử dụng các chuỗi khoảng trắng tùy ý làm dấu phân cách cut. Để sử dụng các không gian riêng lẻ làm dấu phân cách trong awk, hãy đặt dấu phân cách trường thành biểu thức chính quy phù hợp với một không gian duy nhất, không phải là biểu thức chính bao gồm một không gian duy nhất (đó là trường hợp đặc biệt có nghĩa là bất kỳ chuỗi khoảng trắng nào, tức là mặc định) : awk -F '[ ]' '/WORD/ {print $2}'.

¹ Nguyên tắc đầu tiên của Tối ưu hóa chương trình: Đừng làm điều đó. Quy tắc tối ưu hóa chương trình thứ hai (chỉ dành cho chuyên gia!): Đừng làm điều đó. - Michael A. Jackson


1

Lệnh của bạn,

cat fileName | awk '/WORD/ { print $2 }'

Bạn thậm chí không cần một catlệnh. Bạn có thể thử

awk '/WORD/ { print $2 }' filename

Và lệnh dưới đây chuyển hướng đầu ra từ cat sang grep sau đó để cắt,

cat fileName | grep WORD | cut -f 2 -d ' '

Có lẽ chúng ta phải tránh chuyển hướng đầu ra. Awk thực hiện công việc trong một dòng nhưng cutcần một greplệnh để chỉ nhận các dòng có chứa từ cụ thể và nó in cột 2 theo không gian dấu phân cách.

Bạn có thể làm những điều trong awk nếu cắt không làm được.


3
ps bạn cũng không cần lệnh mèo cho grep. Bạn chỉ có thể làm grep WORD filename.
phoops

@ edvinas.me vâng.
Avinash Raj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.