Làm thế nào để bạn xuất tên tệp trong lệnh find trong khi sử dụng -exec?


33

Tôi sử dụng dòng sau để tìm tất cả các thư mục con của PWD và chạy svnadmin verifytrên mỗi thư mục (Tôi đã biết rằng chúng là kho lưu trữ Subversion)

find ./* -maxdepth 0 -exec svnadmin verify {} \;

Điều này hoạt động tốt, khác với thực tế là đầu ra trông như thế này:

* Verifying repository metadata ...
* Verifying metadata at revision 1 ...
* Verifying metadata at revision 2 ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 9 ...
* Verifying metadata at revision 10 ...
* Verifying metadata at revision 12 ...
* Verifying metadata at revision 14 ...
* Verifying metadata at revision 15 ...
* Verifying metadata at revision 18 ...
* Verifying metadata at revision 20 ...
* Verifying metadata at revision 22 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.
* Verified revision 10.
* Verified revision 11.
* Verified revision 12.
* Verified revision 13.
* Verified revision 14.
* Verified revision 15.
* Verified revision 16.
* Verified revision 17.
* Verified revision 18.
* Verified revision 19.
* Verified revision 20.
* Verified revision 21.
* Verified revision 22.
* Verified revision 23.
* Verified revision 0.
* Verifying repository metadata ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 7 ...
* Verifying metadata at revision 9 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.

Tôi thực sự muốn findin tên tệp trước khi thực hiện svnadmin verifylệnh, để đăng nhập dễ dàng hơn.

Tôi đã cố gắng vắt một chút lstrong đó nhưng vùi nó lên, làm thế nào để làm điều này (tốt nhất là đơn giản)?

Câu trả lời:


36

chỉ cần thêm một -printftùy chọn trước

find -printf '%p' -exec command \;

4
Thật đáng yêu, tôi đã đổi '%p'thành '%p\n'tên trước đầu ra xác minh trên dòng riêng của nó.
Arronical

17
@Arronical nếu đó là định dạng bạn muốn, bạn có thể thay thế (được định dạng) -printf '%p\n'bằng đơn giản hơn-print
Steeldo

4
find -name <a_name> -print -exec command {} \;
toliveira 15/03/2017

14

Nếu bạn không muốn tái diễn, không có điểm nào trong việc sử dụng find. Nó là đơn giản hơn nhiều để làm điều đó trong vỏ trực tiếp:

for d in */; do echo "$d"; svnadmin verify "$d"; done

Các for d in */sẽ tìm thấy tất cả các thư mục (các */Đảm bảo chỉ các thư mục và không có tập tin được tìm thấy); những echo "$d"sẽ in tên của thư mục; những svnadmin verify "$d"sẽ kiểm tra thư mục.

Điều này có thể được chạy trực tiếp từ dòng lệnh hoặc từ trong tập lệnh mà không thay đổi định dạng.


1
Đây có vẻ là một cách tốt hơn để đạt được mục tiêu của tôi, nhưng tôi đã phải đưa ra câu trả lời cho Fiximan chỉ vì tiêu đề và câu hỏi của tôi tham khảo findrất nhiều. Cảm ơn vì đã cải thiện kiến ​​thức của tôi!
Arronical

Điều này đòi hỏi phải sử dụng một quả địa cầu. Globbing chắc chắn rất hữu ích và mạnh mẽ, nhưng theo kinh nghiệm cá nhân của tôi, cú pháp khó cài đặt hơn và cuối cùng thường cần những thứ khác như dotglobglobstartrong bash, tạo ra một kịch bản dài hơn, phức tạp hơn. Tôi có xu hướng tiết kiệm các khối cho các tác vụ phức tạp lớn, trong khi findcú pháp dễ dàng hơn để kết hợp với nhau một cách nhanh chóng bằng cách kết hợp một loạt các bộ lọc và lệnh thành một lớp.
dùng5359531

@ user5359531 không phải globalstar hay dotglob (trừ khi bạn biết bạn có các tập tin ẩn và thực sự muốn chúng) đều cần thiết ở đây. Đây rõ ràng là một vấn đề về quan điểm nhưng bạn là người đầu tiên tôi từng gặp, người coi định dạng khá khó hiểu của findđơn giản hơn. Tôi luôn thích sự hả hê hơn findvì tôi không chỉ thấy chúng đơn giản hơn nhiều mà còn an toàn hơn khi xử lý các tên tệp tùy ý được truyền cho các chương trình khác.
terdon

6
find ./* -maxdepth 0 -type d -exec bash -c 'echo "{}"; svnadmin verify "{}"' \;

Tôi đã thêm -type dnếu nó chỉ là thư mục.


Tôi xin trích dẫn {}, ít nhất là trongsvnadmin verify {}
kos

Cảm ơn các phản ứng nhanh chóng. Vì vậy, trong lệnh này, -execsinh ra một shell con, trong đó 2 lệnh được chạy, sử dụng ;như là cuối dòng?
Arronical

5

Thử đi:

for f in * ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

Nếu bạn chỉ muốn thư mục (Cảm ơn @kos lưu ý):

for f in */ ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

Đẹp, nhưng điều này cũng sẽ xử lý các tệp: for f in */sẽ chỉ xử lý các thư mục
kos

Điều này sẽ chỉ làm việc trong một kịch bản? Hoặc tôi có thể phát hành nó trên dòng lệnh?
Arronical

1
@Arronical cũng sẽ hoạt động như một dòng lệnh
Maythux

2
  • Sử dụng . -maxdepth 1thay vì ./*, bạn chỉ cần cấp độ đầu tiên trong cấu trúc thư mục
  • Sử dụng -type d, bạn chỉ cần thư mục
  • Sử dụng ! -name ".", bạn không cần.
  • Sử dụng -execđể bắt đầu một vỏ
  • Sử dụng sh -cđể bắt đầu các lệnh bên trong shell

Lệnh của bạn

find . -maxdepth 1 -type d ! -name "." -exec sh -c 'echo "{}"; svnadmin verify "{}"' \;

hoặc ngắn hơn

  • Sử dụng -prunenếu tập tin là một thư mục, không đi vào nó

Lệnh của bạn

find . -mindepth 1 -prune -exec sh -c 'echo "{}"; svnadmin verify "{}"' \; 

-prunetrông có vẻ thú vị. Tôi đã sử dụng ./* -maxdepth 0để tránh trở về .từ lệnh find. Nó không gây ra bất kỳ lỗi nghiêm trọng nào, nhưng tôi không muốn có lỗi đó trong đầu ra của mình.
Arronical

1

findcó cờ tùy chọn để in, đã được đề cập trong các câu trả lời khác. Nếu chúng ta xem xét vấn đề dưới dạng phối cảnh thực thi nhiều lệnh cho cùng một tệp hiện đang được xử lý, findcho phép sử dụng nhiều -execcâu lệnh. Điều này có nghĩa là chúng tôi có thể chọn sử dụng:

find ./* -maxdepth 0 -exec echo {} \; -exec svnadmin verify {} \; 

Một lần nữa, lưu ý rằng phương pháp này được áp dụng cho không chỉ in với echo, printfhoặc các tiện ích khác, mà còn các lệnh khác.


0

Nó có thể hữu ích để dẫn findđầu ra đến readvòng lặp:

find . | while read d; do echo "=== ${d}: ==="; svnadmin verify ${d}; done

Nó cho phép bạn thực thi chuỗi lệnh phức tạp hơn, phức tạp hơn với tên tệp được trả về find, như trong lsví dụ ưa thích này :

find . | while read f; do echo ${f} | figlet -k; done

-1

Điều này sẽ in tên và nội dung của các tệp chỉ đệ quy ..

find . -type f -printf '\n\n%p:\n' -exec cat {} \;
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.