Sự khác biệt giữa Perl, Python, AWK và sed là gì? [đóng cửa]


253

chỉ muốn biết sự khác biệt chính giữa chúng là gì? và sức mạnh của từng ngôn ngữ (nơi sử dụng nó tốt hơn).

Chỉnh sửa: không phải là "so với" thích chủ đề, chỉ cần thông tin.


142
Những loại câu hỏi được gọi là không mang tính xây dựng này thực sự hữu ích.
Hơi nước

10
Chắc chắn, một tab trên trang đầu để tìm thấy chúng sẽ tiện dụng ...

Để biết sự hữu ích của trăn trên dòng lệnh, hãy xem pyp
Neil McGuigan

Câu trả lời:


550

Trong thứ tự xuất hiện, các ngôn ngữ là sed, awk, perl, python.

Các sedchương trình là một trình soạn thảo dòng và được thiết kế để áp dụng các hành động từ một kịch bản với từng ngành nghề (hay tổng quát hơn, để dãy nhất định của dòng) của tập tin đầu vào hoặc các tập tin. Ngôn ngữ của nó dựa trên edtrình soạn thảo Unix và mặc dù nó có các điều kiện, v.v., thật khó để làm việc với các tác vụ phức tạp. Bạn có thể làm phép lạ nhỏ với nó - nhưng với chi phí cho tóc trên đầu của bạn. Tuy nhiên, nó có lẽ là chương trình nhanh nhất khi thử các tác vụ trong phạm vi của nó. (Nó có các biểu thức chính quy ít mạnh nhất của các chương trình được thảo luận - đủ cho nhiều mục đích, nhưng chắc chắn không phải là PCRE - Biểu thức chính quy tương thích Perl)

Các awkchương trình (tên từ tên viết tắt của tác giả của nó - Aho, Weinberger, và Kernighan) là một công cụ ban đầu để định dạng báo cáo. Nó có thể được sử dụng như một cải tiến sed; trong các phiên bản gần đây hơn, nó đã được tính toán hoàn chỉnh. Nó sử dụng một ý tưởng thú vị - chương trình dựa trên 'mẫu phù hợp' và 'hành động được thực hiện khi mẫu phù hợp'. Các mô hình khá mạnh mẽ (Biểu thức chính quy mở rộng). Ngôn ngữ cho các hành động tương tự như C. Một trong những tính năng chính awklà nó tự động phân tách đầu vào thành các bản ghi và mỗi bản ghi thành các trường.

Perl được viết một phần là một kẻ giết người khủng khiếp và kẻ giết người quyến rũ. Hai trong số các chương trình được cung cấp cùng với nó a2ps2pđể chuyển đổi awktập lệnh và sedtập lệnh thành Perl. Perl là một trong những ngôn ngữ kịch bản thế hệ tiếp theo sớm nhất (Tcl / Tk có thể có thể yêu cầu tính ưu việt). Nó có xử lý biểu thức chính quy tích hợp mạnh mẽ với một ngôn ngữ mạnh mẽ hơn nhiều. Nó cung cấp quyền truy cập vào hầu hết tất cả các cuộc gọi hệ thống và có khả năng mở rộng của các mô-đun CPAN. (Không awkphải cũng không sedthể mở rộng.) Một trong những phương châm của Perl là "TMTOWTDI - Có nhiều hơn một cách để làm điều đó" (phát âm là "tim-toady"). Perl có 'đối tượng', nhưng nó là một phần bổ trợ hơn là một phần cơ bản của ngôn ngữ.

Python được viết lần cuối và có lẽ một phần là phản ứng với Perl. Nó có một số ý tưởng cú pháp thú vị (thụt lề để chỉ mức độ - không có dấu ngoặc hoặc tương đương). Nó thiên về cơ bản hướng đối tượng hơn Perl; nó cũng có thể mở rộng như Perl.

OK - khi nào nên sử dụng từng?

  • Sed - khi bạn cần thực hiện chuyển đổi văn bản đơn giản trên các tệp.
  • Awk - khi bạn chỉ cần định dạng đơn giản và so sánh hoặc chuyển đổi dữ liệu.
  • Perl - cho hầu hết mọi tác vụ, nhưng đặc biệt khi tác vụ cần các biểu thức chính quy phức tạp.
  • Python - cho các tác vụ tương tự mà bạn có thể sử dụng Perl cho.

Tôi không biết bất cứ điều gì mà Perl có thể làm mà Python không thể, hoặc ngược lại. Sự lựa chọn giữa hai sẽ phụ thuộc vào các yếu tố khác. Tôi đã học Perl trước khi có Python, vì vậy tôi có xu hướng sử dụng nó. Python có cú pháp được tích lũy ít hơn và thường đơn giản hơn để học. Perl 6, khi nó trở nên có sẵn, sẽ là một sự phát triển hấp dẫn.

(Lưu ý rằng 'tổng quan' của Perl và Python, đặc biệt, là chưa hoàn chỉnh; toàn bộ sách có thể được viết về chủ đề này.)


82
Một bài viết ++++, sẽ đọc lại!
Robert Gamble

24
tuyệt vời đặc biệt là "khi nào nên sử dụng từng phần"
Khaled Al Hourani

6
lưu ý rằng zen của python về cơ bản là phản đề của TMTOWTDI vì vậy tôi sẽ nói nó có thể là một phản ứng với perl. iirc TCL hơi sau perl và cũng khá phản động với perl, mặc dù phản ứng của TCL là theo cú pháp và độ phức tạp của ngôn ngữ, không phải là cách để làm mọi thứ
jk.

7
Dù mục đích ban đầu là gì, rõ ràng là sự phát triển Python sau này và cộng đồng python đã ưu tiên khả năng đọc và tính nhất quán hơn cú pháp linh hoạt nhưng ngắn gọn hơn của Perl. Bài viết xuất sắc Jonathan
Martin Beckett

4
@blasto: Đối với ETL, tôi muốn ưu tiên awkhơn sedcho việc học (mặc dù cả hai vẫn còn sử dụng của họ). Về kích thước của nhiệm vụ: sedlà tốt nhất khi nó xử lý một dòng tại một thời điểm, không có lưu trữ từ dòng này sang dòng khác. awkthường được sử dụng để xây dựng các mảng kết hợp với dữ liệu được tích lũy từ tất cả các nguồn; nó sử dụng nhiều bộ nhớ hơn và do đó có nhiều khả năng gặp vấn đề với các tập dữ liệu lớn hơn sed. Tôi đã không nghe nói tsawktrước khi bạn liên kết với nó. Tôi có xu hướng quay trở lại Perl (nhưng bạn có thể làm tốt hơn với Python) khi một nhiệm vụ quá nhiều awk.
Jonathan Leffler

91

Sau khi thành thạo vài chục ngôn ngữ, bạn cảm thấy mệt mỏi với những người như S. Lott (xem câu trả lời gây tranh cãi của anh ấy cho câu hỏi này, gần một nửa số phiếu giảm xuống (+ 45 / -22) sáu năm sau khi trả lời).

Sed là công cụ tốt nhất cho các đường ống dòng lệnh cực kỳ đơn giản. Trong tay của một bậc thầy sed, nó phù hợp với một lần phức tạp tùy ý, nhưng nó không nên được sử dụng trong mã sản xuất ngoại trừ trong các đường ống thay thế rất đơn giản. Những thứ như 's / this / that /.'

Gawk (GNU awk) cho đến nay là sự lựa chọn tốt nhất cho việc định dạng lại dữ liệu phức tạp khi chỉ có một nguồn đầu vào duy nhất và một đầu ra duy nhất (hoặc, nhiều đầu ra được viết tuần tự). Vì rất nhiều công việc trong thế giới thực phù hợp với mô tả này, và một lập trình viên giỏi có thể học gawk trong hai giờ, đó là sự lựa chọn tốt nhất. Trên hành tinh này, đơn giản và nhanh hơn là tốt hơn!

Perl hoặc Python tốt hơn nhiều so với bất kỳ phiên bản awk hoặc sed nào khi bạn có các kịch bản đầu vào / đầu ra rất phức tạp. Vấn đề càng phức tạp, bạn càng sử dụng python tốt hơn, từ quan điểm bảo trì và dễ đọc. Tuy nhiên, lưu ý rằng một lập trình viên giỏi có thể viết mã có thể đọc được bằng bất kỳ ngôn ngữ nào và một lập trình viên tồi có thể viết crap không thể nhầm lẫn bằng bất kỳ ngôn ngữ hữu ích nào, vì vậy việc lựa chọn perl hoặc python có thể được để lại theo sở thích của lập trình viên một cách an toàn lành nghề và khéo léo.


9
Đồng ý 100%. Biết hầu hết, nếu không phải tất cả các công cụ VÀ khi nào nên sử dụng từng công cụ là điều giúp phân biệt một kỹ thuật viên giỏi với một công cụ tầm thường.
ata

6
Tôi sẽ thêm rằng một lý do khác để chọn Python hoặc Perl thay vì awk là khi các yêu cầu chuyển đổi của bạn liên quan đến xác thực hoặc logic phức tạp mà ngôn ngữ khác có mô-đun mạnh mẽ hiện có. Hãy suy nghĩ về những gì sẽ cần để xử lý đúng cách, ví dụ như email hoặc địa chỉ đường phố trong awk và bạn sẽ thấy ý tôi là: perl và python có các thư viện làm cho những thứ tầm thường này, trong những thứ này không phổ biến hoặc không có sẵn.
Bọ Cạp

3
Trên thực tế, vì Perl được thiết kế để bao gồm cả Sed và Awk; Tôi thấy dễ dàng hơn khi chỉ viết nó bằng Perl, thay vì học Sed hoặc Awk.
Brad Gilbert

@BradGilbert: như tôi vừa đề cập trong câu trả lời hàng đầu, một lời cảnh báo của Perl (& Python, ruby, v.v.) trên awk là một loại regrec nào đó
Olivier Dulac

1
@OlivierDulac Có cho thấy một trường hợp bệnh lý. Nếu bạn thay đổi từ a?ⁿaⁿđể a??ⁿaⁿsau đó chạy mà trong Perl 5 với 1.000.000 nó chạy trong vòng chưa đầy hai giây. time perl -E '$x=1_000_000;$_="a"x$x;$m=("a??"x$x).("a"x$x);say $_=~$m'Nếu bạn chạy một cái ngây thơ thì chỉ mất hơn hai giây cho một giây . Điều bạn phải nhận ra là Perl có nhiều tính năng regex hơn những tính năng nhanh hơn bao gồm cho phép bạn có mã Perl bên trong regex thay đổi những gì nó khớp . Bạn có thể triển khai một mô-đun hoán đổi tích hợp cho một trong những mô-đun khác nếu bạn muốn.
Brad Gilbert

21

Tôi sẽ không gọi sed là ngôn ngữ lập trình chính thức, nó là một trình soạn thảo luồng với các cấu trúc ngôn ngữ nhằm chỉnh sửa các tệp văn bản theo chương trình.

Awk là một chút của ngôn ngữ mục đích chung nhưng nó vẫn phù hợp nhất để xử lý văn bản.

Perl và Python là ngôn ngữ lập trình mục đích chung. Perl có nguồn gốc từ việc xử lý văn bản và có một số cấu trúc giống như awk (thậm chí còn có một kịch bản awk-to-perl trôi nổi trên mạng). Có nhiều sự khác biệt giữa Perl và Python, cách tốt nhất của bạn có lẽ là đọc các bản tóm tắt của cả hai ngôn ngữ trên một thứ gì đó như Wikipedia để hiểu rõ về chúng là gì.


2
Tôi đã thấy một triển khai sed của Sokoban, trong đó ngụ ý Turing Complete. Tuy nhiên, điều đó cũng có thể nói về sendmail.cf và TeX.
Mối quan tâmOfTunbridgeWells

7
Tôi đã làm việc với một anh chàng đã từng viết PostScript để biến máy in laser thành bộ định tuyến.
Sam Kington

10
@Sam: Wow! Tôi không biết tia laser của máy in có thể được điều chỉnh đủ để cắt gỗ! Oh, xin lỗi, sai loại bộ định tuyến.
Tạm dừng cho đến khi có thông báo mới.

2
sed, không phải là một ngôn ngữ đầy đủ? Chà, điều đó không hoàn toàn đúng, vì sed đã hoàn tất ;)
bernard paulus

1
Tôi đã thấy một triển khai ngôn ngữ thứ tư trong awk. (Vì awk có thể được coi là một trình phân tích cú pháp bằng quyền riêng của mình, nên việc triển khai một trình thông dịch trong đó khá đơn giản).
Tatjana Heuser

19

Đầu tiên, có hai thứ không liên quan trong danh sách "Perl, Python awk và sed".

Điều 1 - công cụ thao tác văn bản đơn giản.

  • sed. Nó có một phạm vi công việc cố định, tương đối đơn giản được xác định bởi ý tưởng đọc và kiểm tra từng dòng của một tệp. sed không được thiết kế để đặc biệt dễ đọc Nó được thiết kế rất nhỏ và rất hiệu quả trên các máy chủ unix rất nhỏ.

  • ôi Nó có một chút ít cố định, phạm vi công việc ít đơn giản hơn. Tuy nhiên, vòng lặp chính của chương trình awk được xác định bằng cách đọc ngầm định các dòng của tệp nguồn.

Đây không phải là ngôn ngữ lập trình "hoàn chỉnh". Trong khi bạn có thể - với một số công việc - viết các chương trình khá phức tạp trong awk, nó nhanh chóng trở nên phức tạp và khó đọc.

Điều 2 - ngôn ngữ lập trình mục đích chung. Chúng có nhiều loại câu lệnh phong phú, nhiều cấu trúc dữ liệu tích hợp và không có giả định hoặc phím tắt có dây để nói.

  • Perl.

  • Con trăn.

Khi nào nên sử dụng chúng.

  • sed. Không bao giờ. Nó thực sự không có bất kỳ giá trị nào trong kỷ nguyên hiện đại của máy tính với hơn 32K bộ nhớ. Perl hoặc Python làm những điều tương tự rõ ràng hơn.

  • ôi Không bao giờ. Giống như sed, nó phản ánh một kỷ nguyên sớm hơn của máy tính. Thay vì duy trì ngôn ngữ này (ngoài tất cả các ngôn ngữ khác cần thiết cho một hệ thống thành công), sẽ dễ chịu hơn khi chỉ cần làm mọi thứ bằng một ngôn ngữ dễ chịu.

  • Perl. Bất kỳ vấn đề lập trình của bất kỳ loại. Nếu bạn thích cú pháp tư duy tự do, nơi có nhiều, nhiều cách để làm điều tương tự, perl rất thú vị.

  • Con trăn. Bất kỳ vấn đề lập trình của bất kỳ loại. Nếu bạn thích cú pháp khá hạn chế, nơi có ít lựa chọn hơn, ít tinh tế hơn và (có lẽ) rõ ràng hơn. Bản chất hướng đối tượng của Python làm cho nó phù hợp hơn cho các vấn đề lớn, phức tạp.

Bối cảnh - Tôi không bash sed và awk ra khỏi sự thiếu hiểu biết. Tôi đã học awk hơn 20 năm trước. Đã làm nhiều điều với nó; được sử dụng để dạy nó như là một kỹ năng unix cốt lõi. Tôi đã học Perl khoảng 15 năm trước. Đã làm nhiều điều tinh vi với nó. Tôi đã bỏ lại cả hai phía sau vì tôi có thể làm những điều tương tự trong Python - và nó đơn giản và rõ ràng hơn.

Có hai vấn đề nghiêm trọng với sed và awk, không phải tuổi của họ.

  1. Sự không hoàn hảo của việc thực hiện của họ. Mọi thứ sed và awk làm đều có thể được thực hiện bằng Python hoặc Perl, thường đơn giản hơn và đôi khi cũng nhanh hơn. Một đường ống vỏ có một số lợi thế về hiệu suất vì đa xử lý của nó. Python cung cấp một subprocessmô-đun để cho phép tôi phục hồi những lợi thế đó.

  2. Sự cần thiết phải học một ngôn ngữ khác. Bằng cách thực hiện mọi thứ trong Python (hoặc Perl), việc triển khai của bạn phụ thuộc vào ít ngôn ngữ hơn, dẫn đến sự gia tăng rõ ràng.


66
Một số đối số khá mệt mỏi chống lại awk / sed. Cờ lê có thể điều chỉnh đã không thay thế cờ lê mở vì lý do tương tự sed và awk vẫn xuất xưởng. Đôi khi công cụ đơn giản là tốt nhất cho công việc. Tôi viết rất nhiều perl, nhưng đối với một chuỗi các lệnh đơn giản, awk / sed nhanh hơn perl -e
RET

27
Bạn không thể giả sử có sẵn bất cứ thứ gì ngoại trừ sh, sed và awk trên hầu hết các hệ thống unix không phải linux. Nếu bạn muốn một cái gì đó hoạt động trên bản cài đặt Solaris, HP / UX hoặc AIX ngoài luồng, bạn sẽ bị mắc kẹt với sed và awk.
Mối quan tâmOfTunbridgeWells

27
Một nửa các kịch bản shell của tôi sử dụng sed hoặc awk. Họ còn lâu mới chết. Python là ngôn ngữ kịch bản ưa thích của tôi, nhưng đôi khi sed và awk là công cụ tốt nhất cho công việc. Chỉ vì chúng đã được sử dụng trong nhiều năm, không có nghĩa là chúng đã lỗi thời.
Jeremy Cantrell

16
@ S.Lott: Tôi không gợi ý rằng bất kỳ ai cũng nên cố gắng xây dựng một ứng dụng web trong awk, nhưng để nói rằng chúng không bao giờ nên được sử dụng là một chút thái quá. Đối với một s & r và / hoặc tinh chỉnh đơn giản (đặc biệt là tệp văn bản được phân tách), perl -e hoặc python -c sẽ không bao giờ hiệu quả như một lớp lót sed / awk.
RET

25
Tôi không thích câu trả lời như thế này. Sed và awk rất dễ hiểu trong một vài giờ và nhẹ hơn nhiều và có sẵn rộng rãi hơn một ngôn ngữ chính thức. Lập trình Shell có liên quan hơn bao giờ hết, nói rằng "KHÔNG BAO GIỜ" sử dụng công cụ này hoặc công cụ đó bị trì hoãn. Nhưng, liệu ý tưởng bị trì hoãn này có phải là một trong những nền tảng mà Perl nổi lên không? Oh well--
ata

14

Khi nào nên sử dụng chúng: awk - never - S. Lott.

Tôi nghĩ S. Lott hơi bỏ lỡ dấu hiệu với khuyến nghị này. Thực tế là, trên Linux và các môi trường UNIX khác, awk là một công cụ hữu ích được sử dụng với bash, sh và ksh để xử lý văn bản nhanh. Ý tưởng của chính kịch bản là bạn giải quyết vấn đề của mình bằng cách dán cùng công cụ này, công cụ đó. Do đó, trong các tập lệnh quản trị, người ta thường có ls, grep, |, awk, time, ps, v.v. .

Ví dụ, tôi là thành viên của nhóm quản lý vật tư thiết bị paintballdotcom. Trang web thương mại điện tử này dựa trên ngăn xếp LAMP. Để xử lý tự động và chuẩn hóa nguồn cấp dữ liệu từ các nhà cung cấp khác nhau vào cơ sở dữ liệu phía sau, chúng tôi sử dụng và duy trì hỗn hợp các tập lệnh đa dạng, bao gồm bash, perl, php và thậm chí là mong đợi. Mỗi cái có điểm mạnh dựa trên các mô-đun và API có sẵn. Trong các tập lệnh bash, chúng tôi thực hiện các mẫu nhanh khớp và các hành động phù hợp trên các mẫu khi cần bằng cách sử dụng awk mà không cần phải chuyển sang PERL. Một điều tôi cũng muốn chỉ ra, điều chưa được nhấn mạnh trong luồng này, đó là một số lượng lớn các tập lệnh này đã được mua hoặc nhận được từ nguồn mở. Nếu tập lệnh xuất hiện dưới dạng Perl, chúng tôi sẽ duy trì nó dưới dạng Perl; nếu kịch bản đến là Php, chúng tôi duy trì nó là Php; nếu nó đến như bash, chúng tôi duy trì nó như bash;


7
Chính S.Lott đã viết rằng phản hồi mà bạn đã trích dẫn, không phải là brian d foy ...
plusplus

5
như lưu ý phụ về câu trả lời khá cũ này: không bao giờ phân tích đầu ra của ls, thay vào đó hãy sử dụng global. đọc này.
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.