Ответ 1
Проверьте, выводит ли find <dir> -type f
что-либо. Вот пример:
for dir in A B C; do
[ -z "'find $dir -type f'" ] && echo "$dir is empty"
done
Мне нужно найти пустые каталоги для данного списка каталогов. В некоторых каталогах есть каталоги внутри.
Если внутренние каталоги также пусты, я могу сказать, что главный каталог пуст, иначе он не будет пустым.
Как я могу проверить это?
Например:
A>A1(file1),A2 this is not empty beacuse of file1
B>B1(no file) this is empty
C>C1,C2 this is empty
Проверьте, выводит ли find <dir> -type f
что-либо. Вот пример:
for dir in A B C; do
[ -z "'find $dir -type f'" ] && echo "$dir is empty"
done
Это зависит от того, что вы хотите делать с пустыми каталогами. Я использую следующую команду, когда хочу удалить все пустые каталоги в дереве, например test
.
find test -depth -empty -delete
Одно замечание о команде выше: он также удалит пустые файлы, поэтому используйте параметр -type d, чтобы этого не было.
find test -depth -type d -empty -delete
Отбросьте -delete
, чтобы просмотреть файлы и каталоги.
Если ваше определение пустого дерева каталогов состоит в том, что оно не содержит файлов, вы сможете вставить что-то вместе в зависимости от того, возвращает ли find test -type f
что-либо.
find
- отличная утилита, и RTFM рано и часто понимают, как много это можно сделать: -)
Вы можете использовать следующую команду:
find . -type d -empty
find directory -mindepth 1 -type d -empty -delete
Это версия, которую я нашел наиболее интересной. Если выполняется из внутреннего каталога, он удалит все пустые каталоги ниже (каталог считается пустым, если он содержит только пустые каталоги).
Параметр mindepth предотвращает удаление самого каталога, если он оказался пустым.
find . -type d -empty
находит и отображает пустые каталоги и подкаталоги в текущем дереве. Например. результирующий список пустых директорий и поддисков:
./2047
./2032
./2049
./2063
./NRCP26LUCcct1/2039
./NRCP26LUCcct1/2054
./NRCP26LUCcct1/2075
./NRCP26LUCcct1/2070
В каталогах не выполняется никаких операций. Они просто перечислены. Это работает для меня.
Чтобы просто найти пустые каталоги (как указано в заголовке вопроса), ответ mosg верен:
find -type d -empty
Но -empty
может быть недоступен в очень старых версиях find
(например, в случае HP-UX), Если это ваш случай, см. Методы, описанные в следующем разделе. Является ли каталог пустым?.
Это немного сложно: предположим, что каталог MyDir
содержит пустые каталоги. После удаления этих пустых каталогов MyDir
станет пустой папкой и также будет удалена. Поэтому я использую команду rmdir
с опцией --parents
(или -p
), которая также удаляет родительские каталоги, когда это возможно:
find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} +
В старой версии find
оператор +
еще не поддерживается, поэтому вместо него можно использовать ;
:
find -type d -empty -exec rmdir -vp --ignore-fail-on-non-empty {} `;`
Большинство этих ответов объясняют, как проверить, является ли каталог пустым. Поэтому я предоставляю здесь три различных метода, которые я знаю:
[ $(find your/dir -prune -empty) = your/dir ]
d=your/dir
if [ x$(find "$d" -prune -empty) = x"$d" ]
then
echo "empty (directory or file)"
else
echo "contains files (or does not exist)"
fi
вариация:
d=your/dir
if [ x$(find "$d" -prune -empty -type d) = x"$d" ]
then
echo "empty directory"
else
echo "contains files (or does not exist or is not a directory)"
fi
Объяснение:
find -prune
похож на find -maxdepth 0
, используя меньше символовfind -type d
печатает только каталоги find -empty
печатает пустые каталоги и файлы
> mkdir -v empty1 empty2 not_empty
mkdir: created directory 'empty1'
mkdir: created directory 'empty2'
mkdir: created directory 'not_empty'
> touch not_empty/file
> find empty1 empty2 not_empty -prune -empty
empty1
empty2
(( ${#files} ))
Этот трюк составляет 100% bash
, но вызывает (порождает) суб-оболочку. Идея состоит из Bruno De Fraine и улучшена комментарием teambob. Я советую это, если вы используете bash и если ваш script не должен быть переносимым.
files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} ))
then
echo "contains files"
else
echo "empty (or does not exist or is a file)"
fi
Примечание. нет разницы между пустым каталогом и несуществующим (и даже если предоставленный путь является файлом).
[ $(ls -A your/dir) ]
Этот трюк вдохновлен статьей nixCraft, опубликованной в 2007 году. Andrew Taylor ответил в 2008 году и gr8can8dian в 2011 году.
if [ "$(ls -A your/dir)" ]
then
echo "contains files"
else
echo "empty (or does not exist or is a file)"
fi
или однострочная версия бахизма:
[[ "$(ls -A your/dir)" ]] && echo "contains files" || echo "empty or ..."
Примечание. ls
возвращает $?=2
, когда каталог не существует. Но никакой разницы между файлом и пустым каталогом.
Эта рекурсивная функция, похоже, выполняет трюк:
# Bash
findempty() {
find ${1:-.} -mindepth 1 -maxdepth 1 -type d | while read -r dir
do
if [[ -z "$(find "$dir" -mindepth 1 -type f)" ]] >/dev/null
then
findempty "$dir"
echo "$dir"
fi
done
}
Учитывая эту структуру каталогов примера:
. |-- dir1/ |-- dir2/ | `-- dirB/ |-- dir3/ | `-- dirC/ | `-- file5 |-- dir4/ | |-- dirD/ | `-- file4 `-- dir5/ `-- dirE/ `-- dir_V/
Результатом выполнения этой функции будет:
./dir1 ./dir5/dirE/dir_V ./dir5/dirE ./dir5 ./dir2/dirB ./dir2
который пропускает /dir4/dirD
. Если вы переместите рекурсивный вызов findempty "$dir"
после fi
, функция будет включать этот каталог в свои результаты.
Как насчет rmdir *
? Эта команда завершится с ошибкой в непустых каталогах.
Я создал простую структуру следующим образом:
test/
test/test2/
test/test2/test2.2/
test/test3/
test/test3/file
test/test3/file
содержит некоторый нежелательный текст.
Выдача find test -empty
возвращает "test/test2/test2.2
" как единственный пустой каталог.
был бы простой подход,
$ [ "$(ls -A /path/to/direcory)" ] && echo "not empty" || echo "its empty"
и
if [ "$(ls -A /path/to/direcory)" ]; then
echo "its not empty"
else
echo "empty directory"
find . -name -type d -ls |awk '($2==0){print $11}'