Tìm tất cả các tệp với Python Shebang


9

Tôi đang cố chạy séc PEP8 đối với cây nguồn lớn. Cây bao gồm một hỗn hợp các tập tin trong các ngôn ngữ khác nhau. Ý tưởng là kiểm tra tất cả các tập lệnh Python mà không cần phải liệt kê rõ ràng chúng. Phần lớn các tệp này không thực sự có .pyphần mở rộng. Có cách nào đơn giản để tìm tất cả các tệp có từ Python trong shebang hoặc tìm tất cả các tệp sẽ chạy với Python khi được thực thi không?

Câu trả lời:


7

Hãy thử làm điều này:

grep -rl '^#!/.*python' .

Điều tương tự với ack :

ack -rl '^#!/.*python' .

5
Lưu ý rằng mặc dù grep -lsẽ dừng đọc một tệp ngay khi tìm thấy kết quả khớp, nhưng đối với các tệp không khớp, nó sẽ đọc toàn bộ tệp. Nó cũng sẽ tìm thấy các kết quả khớp ở giữa các tệp, vì vậy, ví dụ, nó có thể khớp với một shartệp có chứa các tập lệnh python.
Stéphane Chazelas

14

Với GNU, hoặc FreeBSD hoặc NetBSD hoặc OpenBSD (và có khả năng khác) awk:

find . -type f -exec awk '
  /^#!.*python/{print FILENAME}
  {nextfile}' {} +

Chỉ nhìn vào dòng đầu tiên của mỗi tệp và sẽ chạy vài awkgiây nếu cần.

Các nextfiletuyên bố trên không phải là tiêu chuẩn nhưng được tìm thấy trong một vài triển khai trong đó có một GNU (mà có lẽ nơi nó có nguồn gốc từ).

Mặc dù mã ở trên cũng có vẻ hoạt động trong các triển khai khác, nhưng nextfilecâu lệnh sẽ không làm gì ở đó (sẽ được công nhận là một biểu thức bao gồm một nextfilebiến không đặt ), vì vậy điều đó có nghĩa là tất cả các tệp sẽ được đọc đầy đủ và tên tệp sẽ được in cho mỗi dòng phù hợp.

Nếu các awkhỗ trợ của bạn FNR(như POSIX awks làm nhưng không phải là bản gốc awk, thì trên Solaris /usr/xpg4/bin/awkvà không /usr/bin/awk) và không nextfile, bạn có thể viết nó:

find . -type f -exec awk 'FNR == 1 && /^#!.*python/{print FILENAME}' {} +

Mà vẫn sẽ chạy càng ít awkcàng tốt nhưng sẽ đọc các tệp đầy đủ.

Một cách khác để tránh đọc các tệp đầy đủ và điều đó sẽ hoạt động với mọi awkfindnhưng có nghĩa là chạy một awktệp cho mỗi tệp sẽ là:

find . -type f -exec awk '
  /^#!.*python/{r=1};{exit}
  END {exit(1-r)}' {} \; -print

1
+1, nhưng lệnh cuối cùng cũng khớp với các tệp trống.
l0b0

Điểm tốt @ l0b0. Cập nhật.
Stéphane Chazelas
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.