Đường ống từ một tìm thấy vào grep


8

Tôi đang cố gắng làm gì?

Viết lệnh tìm kiếm bất kỳ tệp nào không được yêu cầu bởi bất kỳ tệp nào khác trong dự án của tôi.

Tôi đã thử những gì?

Tôi đang sử dụng findđể có được một danh sách tên tập tin. Bây giờ tôi muốn sử dụng tên tệp làm chuỗi tìm kiếm (thay vì tệp để tìm kiếm).

Tôi đang sử dụng find server/lib -type f -exec basename {} \; | cut -f 1 -d '.'để lấy danh sách tên tệp của mình và tước bỏ phần mở rộng tệp.

Bây giờ tôi biết rằng đây grep -R --exclude-dir=node_modules <search-string> . -llà những gì tôi muốn chuyển từng tên tệp vào nhưng tôi không biết làm thế nào để vượt qua chúng làm <search-string>đối số.


Thông tin khác

Tôi cũng mơ hồ nhận ra rằng đường ống đến điều này grepcó thể vượt qua toàn bộ kết quả của find(toàn bộ danh sách các tệp) mà tôi rõ ràng không muốn làm như vậy nếu đó là điều tôi sắp làm thì hãy nói cho tôi biết.

Ngoài ra, (mặc dù điều này có lẽ không nằm trong phạm vi của câu hỏi này) vì tôi đang sử dụng điều này như một cách để tìm bất kỳ tên tệp nào grepkhông tìm thấy bất cứ điều gì, bất kỳ lời khuyên nào về việc nhận loại đầu ra này sẽ được đánh giá cao

> <the-command>

filename1
server/lib/foo.js # where these are the list of files in which it appears
test/lib/foo.js

filename2
Not Found! #where `filename2` wasn't found anywhere (obviously)

Câu trả lời:


2

Câu trả lời ngắn:

Nếu bạn chỉ muốn chuyển một loạt các dòng làm đối số cho một lệnh khác, thì xargslà bạn của bạn - trong trường hợp này, vì bạn đang đặt nó vào giữa một lệnh, bạn sẽ muốn sử dụng -I {}cờ. Điều này đặt {}làm trình giữ chỗ để bạn có thể đặt bất cứ nơi nào (bạn có thể đặt trình giữ chỗ của riêng mình, nhưng tôi thường tuân theo {}vì nó sẽ không bị nhầm lẫn với nhiều thứ khác.

Đặt tất cả lại với nhau (giả sử các lệnh bạn đã đưa ra làm những gì bạn nghĩ chúng làm!):

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} grep -R --exclude-dir=node_modules {} . -l

Câu trả lời dài

Ok, vì vậy chúng tôi có thể có thể đưa điều này hơn nữa. Giả sử bạn muốn định dạng bạn đã đề cập trước đó - bạn có thể xargsđể sh -cbạn có thể xâu chuỗi các lệnh:

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} sh -c "echo {}; grep -R --exclude-dir=node_modules {} . -l"

Chạy này trên máy tính của tôi, nó trông như thế này là cho bạn các tập tin mà tập tin được tìm thấy. Não tôi mệt mỏi, vì vậy thay vì gói nó thành một kịch bản hay (đó là những gì bạn thực sự nên làm khi oneliners bắt đầu sởn gai ốc, và sử dụng https://www.shellcheck.net/ trong khi bạn ở đó), bạn có thể thay vào đó là bản hack khủng khiếp này (mà tôi nghĩ) sẽ cung cấp cho bạn đầu ra mà bạn đang tìm kiếm:

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} sh -c "echo {}; grep -R --exclude-dir=node_modules {} . -l && printf \"\n\" || printf \"Not found\n\n\""


Rất cảm ơn, có xargs -I {}là những gì tôi đang tìm kiếm.
Simon Legg

6

Với zsh:

projects=(server/lib/**/*(D.:t:r))
grep -rFl --exclude-dir=node_modules -e${(u)^projects} .
  • **/đệ quy đệ quy. Một tính năng được giới thiệu zshvào đầu những năm 90.
  • (D.:t:r)là một vòng loại toàn cầu, một zshtính năng cụ thể cho phép chọn các tệp sử dụng các thuộc tính khác với tên hoặc thay đổi cách sắp xếp hoặc thực hiện sửa đổi trên các tệp tìm thấy.
  • D: bao gồm các tệp chấm và truy cập dấu chấm ngang như mong findmuốn. Rất có thể, bạn muốn tháo cái đó ra.
  • .: chỉ các tệp thông thường (như -type ftrong find)
  • :t, :r: công cụ sửa đổi lịch sử như trong csh/ bashnhưng ở đây được áp dụng cho các tập tin toàn cầu. :tcho đuôi (tên cơ sở), :rcho tên gốc (đã loại bỏ phần mở rộng).
  • x${^array}phân phối các yếu tố như rc's x^$arrayhoặc fish' x$arraysẽ làm. Ví dụ nếu $arraylà ( 1, 2). Điều đó trở thành x1 x2.
  • ${(u)array}(đối với unique), loại bỏ trùng lặp ( (u)là cờ mở rộng tham số).

Để xem danh sách các tập tin có chứa không có các dây, thay thế -lvới -L(giả sử GNU grep, nhưng bạn đã sử dụng tùy chọn GNU cụ thể ở đây). -Fdành cho tìm kiếm chuỗi cố định (vì có lẽ bạn không muốn các tên dự án đó được coi là biểu thức chính quy). Bạn cũng có thể muốn ném vào một -wtùy chọn để grepcho từ trận đấu để fookhông phù hợp trong foobarví dụ (vẫn sẽ phù hợp trong foo-barmặc dù).


Cảm ơn tuyệt vời vì điều này và những lời giải thích, tôi đã không biết về việc projects=(server/lib/**/*(D.:t:r))tạo ra một mảng như thế trong zsh. Tuy nhiên bây giờ tôi cần liệt kê các tập tin grepkhông tìm thấy gì. Tôi đoán tôi cần phải bắt mã thoát 0 / sai?
Simon Legg

@Simon, xem phần về -Lcuối câu trả lời
Stéphane Chazelas

Có tôi đã thấy. -lcho tôi biết kết quả tìm kiếm ở đâu và -Lcho tôi biết nơi nó không được tìm thấy. Nhưng tôi muốn biết một danh sách các thuật ngữ tìm kiếm không tìm thấy ở bất cứ đâu thay vì nơi chúng không được tìm thấy
Simon Legg
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.