Bash, ksh và zsh có giải pháp tốt hơn, nhưng trong câu trả lời này, tôi giả sử vỏ POSIX.
Mẫu .[!.]*
phù hợp với tất cả các tệp bắt đầu bằng dấu chấm theo sau là ký tự không dấu chấm. (Lưu ý rằng [^.]
được hỗ trợ bởi một số shell nhưng không phải tất cả, cú pháp di động để bổ sung bộ ký tự trong các mẫu ký tự đại diện là [!.]
.) Do đó, loại trừ .
và ..
, nhưng cũng có các tệp bắt đầu bằng hai dấu chấm. Mẫu ..?*
xử lý các tệp bắt đầu bằng hai dấu chấm và không chỉ ..
.
chown -R root .[!.]* ..?*
Đây là mẫu cổ điển được đặt để khớp với tất cả các tệp:
* .[!.]* ..?*
Một hạn chế của phương pháp này là nếu một trong các mẫu không khớp với nhau, thì nó được truyền cho lệnh. Trong một tập lệnh, khi bạn muốn khớp tất cả các tệp trong một thư mục ngoại trừ .
và ..
, có một số giải pháp, tất cả chúng đều cồng kềnh:
Sử dụng * .*
để liệt kê tất cả các mục, và loại trừ .
và ..
trong một vòng lặp. Một hoặc cả hai mẫu có thể không khớp với nhau, vì vậy vòng lặp cần kiểm tra sự tồn tại của mỗi tệp. Bạn có cơ hội để lọc các tiêu chí khác; ví dụ: xóa -h
bài kiểm tra nếu bạn muốn bỏ qua các liên kết tượng trưng lơ lửng.
for x in * .*; do
case $x in .|..) continue;; esac
[ -e "$x" ] || [ -h "$x" ] || continue
somecommand "$x"
done
Một biến thể phức tạp hơn trong đó lệnh chỉ được chạy một lần. Lưu ý rằng các tham số vị trí bị ghi đè (vỏ POSIX không có mảng); đặt điều này trong một chức năng riêng biệt nếu đây là một vấn đề.
set --
for x in * .[!.]* ..?*; do
case $x in .|..) continue;; esac
[ -e "$x" ] || [ -h "$x" ] || continue
set -- "$@" "$x"
done
somecommand "$@"
Sử dụng * .[!.]* ..?*
bộ ba. Một lần nữa, một hoặc nhiều mẫu có thể không khớp với nhau, vì vậy chúng tôi cần kiểm tra các tệp hiện có (bao gồm các liên kết tượng trưng lơ lửng).
for x in * .[!.]* ..?*; do
[ -e "$x" ] || [ -h "$x" ] || continue
somecommand "$x"
done
Sử dụng * .[!.]* ..?*
tryptich và chạy lệnh một lần cho mỗi mẫu nhưng chỉ khi nó khớp với thứ gì đó. Điều này chỉ chạy lệnh một lần. Lưu ý rằng các tham số vị trí bị ghi đè (vỏ POSIX không có mảng), hãy đặt nó trong một hàm riêng nếu đây là một vấn đề.
set -- *
[ -e "$1" ] || [ -h "$1" ] || shift
set -- .[!.]* "$@"
[ -e "$1" ] || [ -h "$1" ] || shift
set -- ..?* "$@"
[ -e "$1" ] || [ -h "$1" ] || shift
somecommand "$@"
Sử dụng find
. Với GNU hoặc BSD find, việc tránh đệ quy là dễ dàng với các tùy chọn -mindepth
và -maxdepth
. Với POSIX find, nó khó hơn một chút, nhưng có thể được thực hiện. Biểu mẫu này có ưu điểm là dễ dàng cho phép chạy lệnh một lần thay vì một lần cho mỗi tệp (nhưng điều này không được đảm bảo: nếu lệnh kết quả quá dài, lệnh sẽ được chạy trong một số đợt).
find . -name . -o -exec somecommand {} + -o -type d -prune