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.
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:
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 second
sẽ đượ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 -exec
mệnh đề. Các -false
giữa họ buộc trạng thái thử nghiệm để "false" và -o
nguyê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.
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à find
gọ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 {} \;
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.
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
-o
.