Sử dụng
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
hoặc là
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
hoặc là
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
Thứ tự là quan trọng. Nó đánh giá từ trái sang phải. Luôn bắt đầu với loại trừ đường dẫn.
Giải trình
Không sử dụng -not(hoặc !) để loại trừ toàn bộ thư mục. Sử dụng -prune. Như đã giải thích trong sách hướng dẫn:
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
và trong sổ tay hướng dẫn tìm GNU:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
Thật vậy, nếu bạn sử dụng -not -path "./pathname", find sẽ đánh giá biểu thức cho mỗi nút bên dưới "./pathname".
biểu thức tìm chỉ là đánh giá điều kiện.
\( \)- hoạt động nhóm (bạn có thể sử dụng -path "./tmp" -prune -o -path "./scripts" -prune -o, nhưng nó dài dòng hơn).
-path "./script" -prune- nếu -pathtrả về true và là một thư mục, hãy trả về true cho thư mục đó và không đi xuống nó.
-path "./script" ! -prune- nó đánh giá là (-path "./script") AND (! -prune). Nó hoàn nguyên "luôn đúng" của tỉa thành luôn sai. Nó tránh in "./script"như một trận đấu.
-path "./script" -prune -false- vì -pruneluôn trả về true, bạn có thể theo dõi nó với -falseđể làm tương tự hơn !.
-o- Toán tử HOẶC. Nếu không có toán tử nào được chỉ định giữa hai biểu thức, nó sẽ mặc định là toán tử AND.
Do đó, \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -printđược mở rộng thành:
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
Bản in rất quan trọng ở đây vì nếu không có nó sẽ được mở rộng thành:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-printđược thêm vào bằng cách tìm - đó là lý do tại sao hầu hết thời gian, bạn không cần phải thêm nó vào biểu thức của bạn. Và vì -prunetrả về true nên nó sẽ in ra "./script" và "./tmp".
Nó không cần thiết trong những cái khác vì chúng tôi đã chuyển sang -pruneluôn trả về false.
Gợi ý: Bạn có thể sử dụng find -D opt expr 2>&1 1>/dev/nullđể xem nó được tối ưu hóa và mở rộng như thế nào,
find -D search expr 2>&1 1>/dev/nullđể xem đường dẫn nào được kiểm tra.
_peaks.bed.