ZSH
Tôi biết câu hỏi đã được đánh dấu là bash; nhưng, chỉ để tham khảo, cho người dùng zsh :
Kiểm tra thư mục không trống
Để kiểm tra xem có foo
trống không:
$ for i in foo(NF) ; do ... ; done
trong đó, nếu foo
không trống, mã trong for
khối sẽ được thực thi.
Kiểm tra thư mục trống
Để kiểm tra xem foo
có trống không:
$ for i in foo(N/^F) ; do ... ; done
trong đó, nếu foo
trống, mã trong for
khối sẽ được thực thi.
Ghi chú
Chúng tôi không cần phải trích dẫn thư mục foo
ở trên, nhưng chúng tôi có thể làm như vậy nếu chúng tôi cần:
$ for i in 'some directory!'(NF) ; do ... ; done
Chúng tôi cũng có thể kiểm tra nhiều hơn một đối tượng, ngay cả khi nó không phải là một thư mục:
$ mkdir X # empty directory
$ touch f # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done # echo empty directories
X
Bất cứ thứ gì không phải là thư mục sẽ bị bỏ qua.
Bổ sung
Vì chúng ta đang hình cầu, nên chúng ta có thể sử dụng bất kỳ hình cầu nào (hoặc mở rộng dấu ngoặc nhọn):
$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf # create regular file
$ touch X1/f # directory X1 is not empty
$ touch Y1/.f # directory Y1 is not empty
$ ls -F # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo # print empty directories
X X2 Y Y2
Chúng ta cũng có thể kiểm tra các đối tượng được đặt trong một mảng. Với các thư mục như trên, ví dụ:
$ ls -F # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*) # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z
Do đó, chúng ta có thể kiểm tra các đối tượng có thể đã được đặt trong một tham số mảng.
Lưu ý rằng mã trong for
khối hiển nhiên được thực thi lần lượt trên mọi thư mục. Nếu điều này không mong muốn thì bạn có thể chỉ cần điền một tham số mảng và sau đó thao tác trên tham số đó:
$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories
Giải trình
Đối với người dùng zsh, có (F)
vòng loại toàn cầu (xem man zshexpn
), phù hợp với các thư mục "đầy đủ" (không trống):
$ mkdir X Y
$ touch Y/.f # Y is now not empty
$ touch f # create a regular file
$ ls -dF * # list everything in the current directory
f X/ Y/
$ ls -dF *(F) # will list only "full" directories
Y/
Bộ định tính (F)
liệt kê các đối tượng phù hợp: là một thư mục VÀ không trống. Vì vậy, (^F)
phù hợp với: không một thư mục HOẶC trống. Vì vậy, (^F)
một mình cũng sẽ liệt kê các tệp thông thường, chẳng hạn. Do đó, như đã giải thích trên zshexp
trang man, chúng ta cũng cần bộ định lượng toàn (/)
cầu, chỉ liệt kê các thư mục:
$ mkdir X Y Z
$ touch X/f Y/.f # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z
Do đó, để kiểm tra xem một thư mục nhất định có trống không, do đó bạn có thể chạy:
$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished
và chỉ để đảm bảo rằng một thư mục không trống sẽ không bị bắt:
$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished
Giáo sư! Vì Y
không trống, zsh không tìm thấy kết quả phù hợp nào cho (/^F)
("thư mục trống") và do đó đưa ra thông báo lỗi nói rằng không tìm thấy kết quả phù hợp nào cho toàn cầu. Do đó, chúng tôi cần loại bỏ các thông báo lỗi có thể có này bằng bộ định lượng toàn (N)
cầu:
$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished
Vì vậy, đối với các thư mục trống, chúng ta cần định tính (N/^F)
, mà bạn có thể đọc là: "không cảnh báo tôi về lỗi, thư mục không đầy".
Tương tự như vậy, đối với các thư mục không trống, chúng ta cần định tính (NF)
, tương tự như vậy chúng ta có thể đọc là: "không cảnh báo tôi về lỗi, các thư mục đầy đủ".