Thực hiện một lệnh trong đó một tập tin được tìm thấy


7

Làm thế nào để tôi thực thi một lệnh trong đó một tập tin được tìm thấy?
Hãy xem xét tôi có một thư mục có tên testdirnhư sau:

$ ls -R testdir/
testdir/:
dir1  dir2  dir3  dir4  dir5

testdir/dir1:
doc1.pdf

testdir/dir2:
file1.txt

testdir/dir3:
doc2.pdf

testdir/dir4:
file2.txt

testdir/dir5:
doc5.pdf

Bây giờ tôi muốn thực hiện một hành động (thực thi một lệnh) trong đó findtìm thấy một loại tệp / tệp nhất định. Ví dụ để tôi tìm *.pdf:

$ find . -name '*.pdf'
./testdir/dir3/doc2.pdf
./testdir/dir5/doc5.pdf
./testdir/dir1/doc1.pdf

Bây giờ giả sử tôi muốn thực thi một lệnh (ví dụ nói touch file) trong đó lệnh trên tìm thấy tập tin. Nói cách khác, tôi muốn tạo một tệp có tên filetrong mỗi thư mục nơi .pdftìm thấy ít nhất một tệp để tôi nhận được:

$ ls -R testdir/
testdir/:
dir1  dir2  dir3  dir4  dir5

testdir/dir1:
doc1.pdf  file

testdir/dir2:
file1.txt

testdir/dir3:
doc2.pdf  file

testdir/dir4:
file2.txt

testdir/dir5:
doc5.pdf  file

Làm thế nào để tôi hoàn thành một công việc như vậy?
Có thể cho mỗi lần tìm thấy tệp, cdđến nơi tệp tồn tại và thực hiện lệnh đệ quy.
Tôi biết rằng nó findcó tính năng tuyệt vời: -execnhưng tôi không thể làm cho nó hoạt động.


Đây chỉ là một ví dụ để có được một ý tưởng về những gì tôi muốn làm. Rộng rãi: Làm thế nào để thực thi một lệnh trong đó tập tin được tìm thấy (bởi find) đệ quy?


hoan nghênh chỉnh sửa thẻ nếu có.
Pandya

3
Tìm kiếm của bạn có thể có tùy chọn -execdircho việc này.
meuh

Câu trả lời:


11

Nếu bạn chạy lệnh này, bạn touch filesẽ được chạy, có khả năng nhiều lần, từ thư mục mà lệnh đã được bắt đầu:

find -name '*.pdf' -exec touch file \;

Mặt khác, nếu bạn chạy biến thể này, mỗi phiên bản của lệnh sẽ được chạy trong thư mục của tệp đích:

find -name '*.pdf' -execdir touch file \;

Trong cả hai trường hợp, bạn có thể thấy điều này bằng hành động bằng cách thay thế touch filebằng một trong hai echo {}và / hoặc pwd.


Từ trang web:

-execdir command ;
-execdir command {} +

    Giống như -exec, nhưng lệnh được chỉ định được chạy từ thư mục con chứa tệp phù hợp, thường không phải là thư mục mà bạn đã bắt đầu find.


2

Bạn có thể trích xuất thư mục của tên tệp với dirnamevà lấy nó từ đó, đại loại như thế này:

find . -name "*.pdf" -type f -exec bash myscript {} \;

trong đó tệp myscriptchứa các mục sau:

dir=$(dirname "$1")
cd "$dir"
touch file

nó không hoạt động, bạn đã thử chưa? Nó chỉ được tạo filetrong thư mục mà nó tìm thấy lần đầu tiên
Edward Torvalds

Tôi biết lý do tại sao nó không hoạt động, bây giờ chỉnh sửa câu trả lời của bạn :)
Edward Torvalds

2

Với zshbạn có thể sử dụng vòng loại toàn cầu để chọn ví dụ: chỉ .pdfcác tệp và thông qua các sửa đổi lưu tên thư mục trong một mảng với các phần tử duy nhất và sau đó cdvào từng thư mục đó và chạy lệnh của bạn. Bằng cách này, bạn chỉ chạy lệnh của mình một lần trong mỗi thư mục, bất kể số lượng .pdfs được tìm thấy trong thư mục đó:

dirlist=(**/*.pdf(.:a:h))
for d in ${(u)dirlist[@]}
  (cd $d && touch file)

hoặc là

typeset -U dirlist
dirlist=(**/*.pdf(.:a:h))
for d in ${dirlist}
  (cd $d && touch file)

Bạn có thể kết hợp thêm các công cụ sửa đổi và vòng loại, ví dụ như toàn cầu cho các tệp thông thường (ẩn và không ẩn) với tiện ích mở rộng .bkpvà lưu tên thư mục duy nhất trong một mảng:

dirlist=(**/*.bkp(D.:a:h))

0

Không tìm đâu xa hơn entr:

https://bitbucket.org/eradman/entr

Những gì bạn có thể làm là để entr xem một thư mục được chỉ định. Khi tìm thấy vị trí tệp, chạm vào một tệp có tên, giả sử, triggerfile.txt trong thư mục đó và để entr tiếp quản.

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.