2009-05-14 12 views

Trả lời

264
  1. Piping để quá trình khác (Mặc dù điều này sẽ không đạt được những gì bạn nói bạn đang cố gắng để làm):

    command1 | command2 
    

    này sẽ gửi kết quả của command1 như đầu vào của command2

  2. -exec trên find (điều này sẽ làm những gì bạn muốn làm - nhưng cụ thể là find)

    find . -name '*.foo' -exec cat {} \; 
    

    (Mọi thứ giữa find-exec là các vị từ tìm bạn đã sử dụng. {} sẽ thay thế tệp cụ thể mà bạn đã tìm thấy trong lệnh (cat {} trong trường hợp này); các \; là để kết thúc lệnh -exec)

  3. gửi đầu ra của một quá trình như các đối số dòng lệnh để một quá trình

    command2 `command1` 
    

    ví dụ:.

    cat `find . -name '*.foo' -print` 
    

    (Lưu ý đây là những BACK- QUOTES không phải dấu ngoặc kép thông thường (dưới dấu ngã ~ trên bàn phím của tôi).) Điều này sẽ gửi đầu ra của command1 vào command2 làm đối số dòng lệnh. Lưu ý rằng tên tệp có chứa dấu cách (dòng mới, v.v.) sẽ được chia thành các đối số riêng biệt.

+2

mèo' find -name' * .foo '-print' làm việc tuyệt vời cho tôi ... Cảm ơn –

+0

Các backquotes làm việc tuyệt vời và được tổng quát hơn, bạn có thể sử dụng nó để cat một danh sách các tập tin từ một tập tin là tốt. – Hazok

+11

Lưu ý rằng các phiên bản hiện đại của 'tìm' cho phép bạn viết:' tìm. -name '* .foo' -exec cat {} + ', trong đó' + 'chỉ ra rằng' find' nên nhóm càng nhiều tên tập tin càng thuận tiện vào một lệnh gọi đơn. Điều này là khá hữu ích (nó đề với không gian vv trong tên tập tin mà không cần đến '-print0' và' xargs -0'). –

6

Âm thanh như một công việc cho một kịch bản shell với tôi:

for file in 'find -name *.xml' 
do 
    grep 'hello' file 
done 

hoặc một cái gì đó như thế

+2

Đây là câu trả lời hợp lệ, mặc dù không nhất thiết phải tối ưu cho câu hỏi. –

+1

... vâng, nhưng nó là tuyệt vời nếu bạn muốn có một tập tin lớn với tên tập tin được liệt kê là tốt. –

+1

Tôi thích điều này là tốt nhất. Một khối vòng như thế này rời khỏi phòng để làm những việc khác. – kakyo

62
find . -print | xargs grep something 

Nếu bạn đang ở trên Linux hoặc có GNU findxargs, sau đó sử dụng -print0 với find-0 với xargs để xử lý các tên tệp có chứa dấu cách và các ký tự kỳ quặc khác.

Nếu bạn không muốn tên tệp - chỉ văn bản - sau đó thêm tùy chọn thích hợp vào grep (thường là -h để chặn 'tiêu đề'). Để đảm bảo hoàn toàn tên tệp được in bởi grep (ngay cả khi chỉ tìm thấy một tệp hoặc lệnh gọi cuối cùng là grep chỉ được cung cấp 1 tên tệp), sau đó thêm /dev/null vào dòng lệnh xargs, để luôn có ít nhất hai tên tệp.


Lưu ý rằng POSIX 2008 thêm + đánh dấu để find có nghĩa là nó bây giờ tự động nhóm như nhiều tác phẩm như là hợp lý vào một thực hiện lệnh duy nhất, rất giống xargs không, nhưng với một số ưu điểm:

  1. Bạn không phải lo lắng về các ký tự lẻ trong tên tệp.
  2. Bạn không phải lo lắng về lệnh được gọi với không có tên tệp.

Cả hai vấn đề này với xargs không có tùy chọn -0. Do đó, bạn có thể viết một cách hợp lý:

find . -exec grep something {} + 
+0

Đối với những người bối rối như tôi, lưu ý rằng cách này đầu tiên sẽ cung cấp cho tất cả các đầu ra của tìm, và sau đó cung cấp cho đầu ra của 'xargs grep something'. –

+2

@EricHu: Tôi có thể thấy bạn đang bối rối, nhưng nó không làm những gì bạn nói nó, ít nhất là không phải trên bất kỳ hệ thống dựa trên Unix tôi biết. Đầu ra của 'find' được đưa vào đầu vào chuẩn của' xargs'. Chương trình 'xargs' đọc đầu vào tiêu chuẩn của nó, tách đầu vào ở khoảng trắng (khoảng trắng, dòng mới, tab, vv) và nối thêm một số từ vào lệnh' grep something' và thực hiện dòng lệnh. 'xargs' sau đó tiếp tục đọc đầu vào và thực hiện các lệnh cho đến khi nó hết đầu vào. 'xargs' chạy lệnh' grep' thường xuyên khi cần thiết cho đầu vào được đưa ra (từ 'tìm' trong ví dụ này). –

+0

Ah lỗi của tôi, đây là sử dụng grep để tìm kiếm trong mỗi tệp phù hợp.Tôi đã tìm cách đơn giản lọc đầu ra của lệnh find bằng grep –

2

Lệnh find có một cuộc tranh cãi exec mà bạn có thể sử dụng cho những thứ như thế này, bạn chỉ có thể làm như grep trực tiếp sử dụng đó.

Ví dụ (from here, other good examples at this page):

find . -exec grep "www.athabasca" '{}' \; -print 
-1

bạn đang cố gắng tìm văn bản trong các tập tin? Bạn chỉ có thể sử dụng grep cho rằng ...

grep searchterm * 
30

Có một vài cách để vượt qua danh sách các tập tin được trả về bởi lệnh find để lệnh cat, mặc dù về mặt kỹ thuật không phải tất cả đường ống sử dụng, và không ai thực sự ống trực tiếp đến cat.

  1. Cách đơn giản nhất là sử dụng backticks:

    cat `find [whatever]` 
    

    cách tương đương, người ta có thể sử dụng $() thay vì backticks trong một số vỏ, bao gồm bash:

    cat $(find [whatever]) 
    

    Đây là ít di động, nhưng có thể làm được.

    Cả hai cú pháp đều lấy đầu ra của find và đặt nó trên dòng lệnh cat. Điều này không hoạt động tốt nếu find có quá nhiều đầu ra (nhiều hơn có thể phù hợp trên dòng lệnh) hoặc nếu đầu ra có các ký tự đặc biệt (như khoảng trắng).

  2. Bạn có thể sử dụng find 's -exec hành động, mà thực thi một lệnh cho mỗi tập tin mà nó tìm thấy:

    find [whatever] -exec cat {} \; 
    

    này sẽ chạy cat một lần cho mỗi tập tin duy nhất thay vì chạy một trường hợp duy nhất của cat đi qua nó nhiều tên tệp có thể không hiệu quả và có thể không có hành vi bạn muốn đối với một số lệnh (mặc dù nó tốt cho cat). Cú pháp cũng là một loại khó xử khi gõ - bạn cần phải thoát khỏi dấu chấm phẩy vì dấu chấm phẩy là đặc biệt cho vỏ!

    Một số phiên bản của find (đáng chú ý là hầu hết các phiên bản GNU) cho phép bạn thay thế ; với + sử dụng find 's chế độ thêm để chạy trường ít của cat.

    find [whatever] -exec cat {} + 
    

    Điều này sẽ chuyển nhiều tên tệp cho mỗi lần gọi cat, điều này có thể hiệu quả hơn. Tuy nhiên, hãy lưu ý rằng không phải không phải là để sử dụng một lời gọi đơn lẻ. Nếu dòng lệnh sẽ quá dài thì các đối số được trải rộng trên nhiều lời gọi của cat. Đối với cat, điều này có lẽ không phải là một vấn đề lớn, nhưng đối với một số lệnh khác, điều này có thể thay đổi hành vi theo những cách không mong muốn. Trên các hệ thống Linux, giới hạn chiều dài dòng lệnh là khá lớn, do đó việc chia nhỏ thành nhiều lần gọi là khá hiếm so với một số hệ điều hành khác.

  3. Cách tiếp cận cổ điển/di động là sử dụng xargs:

    find [whatever] | xargs cat 
    

    xargs chạy lệnh quy định (cat, trong trường hợp này), và thêm đối số dựa trên những gì nó đọc từ stdin. Giống như -exec với +, điều này sẽ phá vỡ dòng lệnh nếu cần. Tức là, nếu find tạo ra quá nhiều đầu ra, nó sẽ chạy cat nhiều lần. Như đã đề cập trong phần về -exec trước đó, có một số lệnh mà việc tách này có thể dẫn đến hành vi khác nhau. Lưu ý rằng việc sử dụng xargs như thế này có vấn đề với khoảng trống trong tên tệp, vì xargs chỉ sử dụng khoảng trắng làm dấu phân tách.

  4. Phương pháp mạnh mẽ nhất, di động, và hiệu quả cũng sử dụng xargs:

    find [whatever] -print0 | xargs -0 cat 
    

    Cờ -print0 nói find sử dụng \0 (kí tự null) delimiters giữa tên tập tin, và cờ -0 nói xargs mong đợi những \0 dấu phân cách. Điều này có khá nhiều hành vi giống hệt với cách tiếp cận -exec ... +, mặc dù có tính di động cao hơn (nhưng đáng tiếc là tiết lộ chi tiết hơn).

-1

Để liệt kê và xem nội dung của tất cả các file abc.def trên máy chủ trong thư mục/writing và/JKL

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \; 

Để liệt kê các tập tin abc.def mà đã nhận xét mục và hiển thị thấy những mục trong thư mục/writing và/JKL

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \; 
1

trong bash, sau đây sẽ là thích hợp:

find /dir -type f -print0 | xargs -0i cat {} | grep whatever 

Thao tác này sẽ tìm tất cả các tệp trong thư mục /dir và đặt tên tệp an toàn thành xargs, an toàn sẽ lái xe grep.

Bỏ qua xargs không phải là ý tưởng hay nếu bạn có hàng nghìn tệp trong /dir; cat sẽ bị hỏng do độ dài danh sách đối số quá mức. xargs sẽ sắp xếp tất cả cho bạn.

Đối số -print0 đối với find đối số với -0 đối số để xargs xử lý tên tệp có khoảng trắng chính xác. Đối số -i thành xargs cho phép bạn chèn tên tệp khi được yêu cầu trong dòng lệnh cat. Các dấu ngoặc được thay thế bằng tên tệp được chuyển vào lệnh cat từ find.

2

Đây là bắn tôi để sử dụng chung:

grep YOURSTRING `find .` 

Nó sẽ in tên tập tin

0

này làm việc cho tôi

find _CACHE_* | while read line; do 
    cat "$line" | grep "something" 
done 
9

Để đạt được điều này (sử dụng bash) tôi sẽ làm như sau:

cat $(find . -name '*.foo') 

Điều này được gọi là "thay thế lệnh" và nó ngăn chặn dòng nguồn cấp dữ liệu theo mặc định đó là thực sự thuận lợi! hơn

infos here

0

Sử dụng ggrep.

ggrep -H -R -I "mysearchstring" * 

để tìm kiếm một tập tin trong unix chứa văn bản nằm trong thư mục hiện tại hoặc một thư mục con

4

Dưới đây là cách của tôi để tìm tên file có chứa một số nội dung mà tôi quan tâm, chỉ cần một bash đơn dòng đó độc đáo xử lý khoảng trống trong tên tập tin quá:

find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done 
1

tôi sử dụng một cái gì đó như thế này:

find . -name <filename> -print0 | xargs -0 cat | grep <word2search4> 

Đối số "-print0" đối số cho "tìm" và "-0" cho "xargs" là cần thiết để xử lý khoảng trắng trong đường dẫn tệp/tên chính xác.

Các vấn đề liên quan