Вопрос или проблема
С помощью find
я проверю, существуют ли в директории in
файлы минимального размера 1 байт, и если нет, то выйду.
Я пытался сделать что-то вроде этого, но это не сработало
find ./in/ -type f -iname '*' -size 1c &> /dev/null
if [ "$?" != 0 ]
then
echo размер файла меньше 1 байта, прерываю...
fi
С помощью GNU find
:
if (( $(find -H in -type f -size +0c -printf 1 -quit) )); then
echo Есть по крайней мере один непустой обычный файл
else
echo>&2 "Либо нет обычного файла, либо я не могу читать или искать в директории, либо все обычные файлы пусты"
exit 1
fi
С помощью zsh вместо bash:
if ()(( $# )) in/**/*(NDY1.L+0); then
print Есть по крайней мере один непустой обычный файл
else
print -u2 "Либо нет обычного файла, либо я не могу читать или искать в директории, либо все обычные файлы пусты"
exit 1
fi
Если помимо этого теста вы также хотите получить список непустых файлов в массиве, чтобы можно было обработать его позже в вашем скрипте, в bash 4.4+:
readarray -td '' files < <(find -H in -type f -size +0c -print0)
if (( ! ${#files[@]} )); then
echo>&2 "Либо нет обычного файла, либо я не могу читать или искать в директории, либо все обычные файлы пусты"
exit 1
fi
for file in "${files[@]}"; do
что-то с "$file"
done
В zsh:
for file in in/**/*(D.L+0); do
что-то с $file
done
Без квалификатора N
zsh завершится с сообщением об ошибке, если нет совпадений. Если вы хотите вывести собственное сообщение об ошибке, вы можете сделать это, как в bash
files=( **/*(ND.Y+0) )
if (( ! $#files )); then
print -u2 "Либо нет обычного файла, либо я не могу читать или искать в директории, либо все обычные файлы пусты"
exit 1
fi
for file in $files; do
что-то с $file
done
Некоторые замечания о вашем подходе:
-iname '*'
не имеет смысла, он сопоставляет файлы, имена которых (без учета регистра!?) состоят из разного количества символов, поэтому, кроме потенциально патологических случаев, когда имена файлов состоят из несимволов, он должен сопоставлять все файлы и может быть опущен.-size 1c
сопоставляет файлы, размер которых точно равен 1 байт (c
— это старая интерпретацияc
haracter из тех времен, когда символы всегда состояли из одного байта). Вам нужно-size +0c
для файлов размером хотя бы 1 байт.-size +0
для файлов, размер которых, округленный до следующего 512-байтового блока, больше 0, также сработает здесь.find
возвращает ненулевой код завершения, когда возникает ошибка, препятствующая ему найти файлы, а не когда не найден ни один файл с использованием предоставленного фильтра.- В современных шеллах, похожих на Bourne, вместо
cmd...; if [ "$?" != 0 ]
можно использоватьif ! cmd...
echo размер файла меньше 1 байта, прерываю...
неправильно описывает, что происходит, когда не найдено ни одного непустого файла.
Ответ или решение
Для поиска файлов определённого минимального размера в директории вы можете использовать команду find
в терминале. Ниже я предоставлю несколько подходов для различных сценариев и оболочек.
Общие рекомендации по использованию find
-
Поиск файлов с минимальным размером: Чтобы найти файлы с минимальным размером 1 байт, используйте параметр
-size +0c
. Этот параметр указывает, что вам нужны файлы, размер которых превышает 0 байт. -
Проверка наличия файлов: Чтобы убедиться, что такие файлы существуют, вы можете перенаправить вывод команды и проверить код возврата.
Пример для Bash
Вот пример, который проверяет наличие хотя бы одного файла размером более 0 байт и, в случае, если таких файлов нет, выводит сообщение об ошибке:
if find ./in/ -type f -size +0c -print -quit | grep -q .; then
echo "Существуют файлы размером более 0 байт."
else
echo "Нет файлов или все файлы имеют нулевой размер."
exit 1
fi
Получение списка файлов для последующей обработки
Если вы хотите сохранить список найденных файлов в массив для дальнейшей обработки, вы можете использовать следующий код:
readarray -td '' files < <(find ./in/ -type f -size +0c -print0)
if (( ! ${#files[@]} )); then
echo >&2 "Нет файлов или все файлы имеют нулевой размер."
exit 1
fi
for file in "${files[@]}"; do
echo "Обработка файла: $file"
# Что-то с "$file"
done
Пример для Zsh
Если вы используете Zsh, ниже приведен аналогичный пример:
if (( $# in/**/*(D.L+0) )); then
echo "Существуют файлы размером более 0 байт."
else
print -u2 "Нет файлов или все файлы имеют нулевой размер."
exit 1
fi
Другой способ с использованием массива
Чтобы сохранить файл в массив и обработать его, можно использовать:
files=( **/*(ND.Y+0) )
if (( ! $#files )); then
print -u2 "Нет файлов или все файлы имеют нулевой размер."
exit 1
fi
for file in "${files[@]}"; do
echo "Обработка файла: $file"
# Что-то с $file
done
Заключение
- Убедитесь, что используете правильные параметры
-size
в командеfind
. -iname '*'
не требуется, если вы хотите найти все файлы, так как это условие подходит под любые имена файлов.- Обратите внимание на код возврата команды
find
, который указывает на ошибки при поиске, а не на отсутствие файлов по заданным критериям.
Следуя этим рекомендациям, вы сможете эффективно находить и обрабатывать файлы определённого минимального размера.