Làm cách nào để thực thi nhiều lệnh khi sử dụng find?


57

Tôi đang cố gắng chạy nhiều lệnh trên những thứ tôi đã tìm thấy, làm thế nào tôi có thể đạt được điều này?

find . -exec cmd1; cmd2

dường như không hoạt động; thay vào đó, nó chạy cmd2 sau khi cmd1 được thực thi trên mọi tệp.

Câu trả lời:


40

Trong phần trình diễn này, tôi sẽ sử dụng sh -c 'echo first; false'(hoặc true) cho lần đầu tiên -exec. Điều đó sẽ cung cấp một số đầu ra và cũng có hiệu ứng mã thoát được chọn. Sau đó echo secondsẽ được sử dụng cho cái thứ hai. Giả sử rằng có một tệp trong thư mục hiện tại.

$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second

Một lệnh thực sự của loại này sẽ trông như:

find . -type f \( -exec command1 \; -false -o -exec command2 \; \)

Trong tập thứ hai, các dấu ngoặc đơn thoát được nhóm hai -execmệnh đề. Các -falsegiữa họ buộc trạng thái thử nghiệm để "false" và -onguyên nhân các biểu hiện tiếp theo (thứ hai -exec) được đánh giá vì sự -false.

Từ man find:

expr1 expr2
Hai biểu thức liên tiếp được lấy để được nối với một hàm "và"; expr2 không được đánh giá nếu expr1 sai.

expr1 -a expr2
Tương tự expr1 expr2.

expr1 -o expr2
Hoặc; expr2 không được đánh giá nếu expr1 là đúng.


À đúng rồi, tôi quên mất -o.
Ignacio Vazquez-Abrams

32

Nếu bạn không quan tâm đến việc cmd1 có thể ngăn cmd2 chạy do mã lỗi 0:

find . -exec cmd1 \; -exec cmd2 \;

Cách đáng tin cậy duy nhất để có được cả hai lệnh luôn chạy này là findgọi một trình bao sau đó sẽ chạy các lệnh theo trình tự:

find . -exec bash -c 'cmd1; cmd2' filedumper {} \;

2

Nếu bạn không phiền khi tạo một tập lệnh có cmd1 và cmd2, thì đó chỉ là:

find . -exec myscript {} \;

hoặc là

find . -exec myscript {} +

Sử dụng \; hoặc + tùy thuộc vào việc myscript có thể xử lý nhiều tệp cùng một lúc hay không (có lông nếu có khoảng trắng trong tên tệp, v.v.).

Đặt những gì bạn đang làm vào một kịch bản, theo kinh nghiệm của tôi, hầu như luôn luôn có giá trị. Nếu bạn phải làm điều đó một lần, bạn sẽ phải làm lại.

Nhưng một mẹo nhỏ là đặt phần tìm kiếm bên trong tập lệnh:

if [ $# -gt 0 ]; then
    for each; do
        touch $each
    done
else
    find . -exec $0 {} +
fi

Sau đó, myscript hoạt động trên bất kỳ tệp nào bạn cung cấp làm đối số để nó hoạt động, nhưng nếu bạn không cung cấp cho nó bất kỳ đối số nào, nó sẽ tìm thấy từ thư mục hiện tại và sau đó gọi chính nó trên các tệp tìm thấy. Điều này xoay quanh thực tế là find -exec không thể gọi các hàm shell mà bạn đã xác định trong tập lệnh của mình.


0

Tôi đã thử cả hai giải pháp trước đây mà không gặp nhiều may mắn. Điều này đã làm việc tốt cho tôi:

$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done

Điều này sẽ không hoạt động nếu danh sách các tệp quá lớn.
Alex

-3

thử lệnh:

sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l

4
Eh, đó không phải là một ý tưởng tốt. Phần *trong -execsẽ mở rộng ra tất cả các tệp trong thư mục hiện tại. Đặc biệt là khi chạy như sudo.
slhck
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.