Я должен сделать некоторую очистку папки, и я хотел бы удалить каталоги, которые имеют 10 или меньше файлов в них. Я пытался смотреть на GNU find
, но не было ничего связанного с количеством файлов в каталоге. Какие команды я должен использовать для выполнения этого?
Я не полностью протестировал это, но это должно работать. Можно также использовать find
для выполнения этого.
# Loop over all files
for dir in * **/*; do
# Make sure this is a directory
if [ -d "${dir}" ]; then
# Get the number of files (not including directories) in this directory
FILE_COUNT=`ls $dir -1 | grep -v / | wc -l`
# Check if it's less than 10
if [ $FILE_COUNT -lt 10 ]; then
# Delete the directory
rm -rf "${dir}"
fi
fi
done
Один путь состоял бы в том, чтобы использовать find
-exec
действие для выполнения пользовательского теста количества файлов.
Можно было использовать секунду find
команда наряду с wc
чтобы найти и считать файлы в рамках каждого каталога, но вероятно более оптимальный вариант состоял бы в том, чтобы окружить globbing, чтобы хлебать имена файлов в массив и затем возвратить логическое значение, указывающее, является ли размер массива меньше, чем порог т.е.
files=( dir/* ); ((${#files[@]} < 10))
Соединяя все это, мы должны смочь перечислить все подкаталоги меньше чем с 10 файлами (включая подподкаталоги) использование
find . -depth -type d ! -name '.' -exec bash -c '
shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < ${2:-10}))
' bash {} 10 \; -print0 | xargs -0
(можно скорректировать число 10
после bash {}
для различных порогов - ${2:-10}
расширение параметра делает это значением по умолчанию в 10 файлов, если никакой второй аргумент не дан). Например, данный
$ tree .
.
├── bar
│ ├── file1
│ ├── file2
│ ├── file3
│ ├── file4
│ ├── file5
│ ├── file6
│ ├── file7
│ ├── file8
│ ├── file9
│ └── other file
├── baz
│ ├── other file
│ └── subdir
└── foo
└── somefile
4 directories, 12 files
затем
find . -depth -type d ! -name '.' -exec bash -c '
shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < "${2:-10}"))
' bash {} 10 \; -print0 | xargs -0
./foo ./baz/subdir ./baz
Если это, кажется, делает правильную вещь, можно на самом деле удалить их путем добавления rm -rf
но будьте очень осторожны с этим - помнят, что нет никакой 'отмены'
find . -depth -type d ! -name '.' -exec bash -c '
shopt -s nullglob; files=( "$1"/* ); ((${#files[@]} < ${2:-10}))
' bash {} 10 \; -print0 | xargs -0 rm -rf
( xargs
мог быть устранен при помощи другого -exec
действие для выполнения rm
более непосредственно, но формулировка выше помогает сделать вывод - печать, статистика, удалить или что бы то ни было.)
Обратите внимание, что это будет действовать рекурсивно т.е. каталог, который первоначально имеет больше, чем n
файлы включая подкаталоги могут быть удалены в результате некоторых из тех подкаталогов, самих удаляемых как find
создает резервную копию дерева каталогов - текущий каталог явно защищен от возможного удаления ! -name '.'
тест.
Если Вам не нужен он для действия рекурсивно, можно просто циклично выполниться по каталогам и выполнить то же количество файла и протестировать логику, например, удалить все каталоги первого уровня, содержащие меньше чем 10 файлов в текущем каталоге
shopt -s nullglob
for d in */; do
files=( "$d"/* )
((${#files[@]} < 10)) && echo rm -rf -- "$d"
done