Tôi đã bối rối về lý do tại sao các thư mục được cắt tỉa cũng được in bằng find
lệnh và một số chi tiết phức tạp khác về cách -prune
làm việc, nhưng có thể tìm ra nó với một vài ví dụ.
Để chạy các ví dụ dưới đây, tạo các thư mục và tệp sau đây.
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
Để tạo cấu trúc này:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
Bây giờ sử dụng find để tìm các thư mục có tên aa
. Không có vấn đề ở đây.
$ find . -type d -name aa
./aa
Tìm kiếm tất cả các thư mục khác ngoài aa và chúng tôi nhận được thư mục hiện tại .
và ./bb
, cũng có ý nghĩa.
$ find . -type d ! -name aa
.
./bb
Cho đến nay rất tốt, nhưng khi chúng tôi sử dụng -prune
, tìm trả về thư mục chúng tôi đang cắt, điều này ban đầu làm tôi bối rối vì tôi hy vọng nó sẽ trả về tất cả các thư mục khác chứ không phải thư mục được cắt tỉa.
$ find . -type d -name aa -prune
./aa
Lý do tại sao nó trả về thư mục được cắt tỉa được giải thích, không phải trong -prune
phần của các trang man như được nêu trong câu trả lời của Timo , mà trong EXPRESSIONS
phần:
Nếu biểu thức không chứa hành động nào khác -prune
,
-print
được thực hiện trên tất cả các tệp mà biểu thức là đúng.
điều đó có nghĩa là, vì biểu thức khớp với aa
tên thư mục, nên biểu thức sẽ đánh giá là đúng và nó sẽ được in vì tìm thấy thêm một -print
dấu chấm ở cuối toàn bộ lệnh. -print
Tuy nhiên, nó sẽ không thêm một hành động nếu bạn cố tình thêm hành động -o -print
vào cuối:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Ở đây, lệnh find KHÔNG thêm ẩn -print
nữa, và vì vậy thư mục chúng ta đang cắt tỉa ( aa
) sẽ không được in.
Vì vậy, cuối cùng, nếu chúng ta thêm một mệnh đề tìm kiếm các tệp có mẫu tên tệp file*
sau -o
, thì bạn phải đặt một -print
mệnh đề ở cuối mệnh đề thứ hai như thế này:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
Lý do tại sao điều này hoạt động giống nhau: Nếu bạn không đặt -print
mệnh đề thứ hai, thì vì không có hành động nào khác ngoài -prune
hành động, find sẽ -print
tự động thêm vào lệnh END, khiến -prune
mệnh đề in ra thư mục cắt tỉa:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
Nói chung, bạn cần đặt -print
lệnh trong mệnh đề thứ hai. Nếu bạn đặt nó ở giữa như poster gốc đã làm, nó sẽ không hoạt động chính xác vì các tệp được cắt sẽ được in ngay lập tức và mệnh đề thứ hai sẽ không có cơ hội chọn các tệp mà nó muốn:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Thật không may, người đăng ban đầu đã nhận lệnh sai ở trên bằng cách đặt -print
sai vị trí. Nó có thể đã làm việc cho trường hợp cụ thể của anh ta, nhưng nó không hoạt động trong trường hợp chung.
Có hàng ngàn người gặp khó khăn trong việc hiểu cách làm -prune
việc. Các find
trang người đàn ông cần được cập nhật để ngăn chặn sự nhầm lẫn trên toàn thế giới Neverending về lệnh này.
-print
, nếu không thì ngầm-print
áp dụng cho toàn bộ điều kiện