Как найти файлы определённого минимального размера?

Вопрос или проблема

С помощью 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 — это старая интерпретация character из тех времен, когда символы всегда состояли из одного байта). Вам нужно -size +0c для файлов размером хотя бы 1 байт. -size +0 для файлов, размер которых, округленный до следующего 512-байтового блока, больше 0, также сработает здесь.
  • find возвращает ненулевой код завершения, когда возникает ошибка, препятствующая ему найти файлы, а не когда не найден ни один файл с использованием предоставленного фильтра.
  • В современных шеллах, похожих на Bourne, вместо cmd...; if [ "$?" != 0 ] можно использовать if ! cmd...
  • echo размер файла меньше 1 байта, прерываю... неправильно описывает, что происходит, когда не найдено ни одного непустого файла.

Ответ или решение

Для поиска файлов определённого минимального размера в директории вы можете использовать команду find в терминале. Ниже я предоставлю несколько подходов для различных сценариев и оболочек.

Общие рекомендации по использованию find

  1. Поиск файлов с минимальным размером: Чтобы найти файлы с минимальным размером 1 байт, используйте параметр -size +0c. Этот параметр указывает, что вам нужны файлы, размер которых превышает 0 байт.

  2. Проверка наличия файлов: Чтобы убедиться, что такие файлы существуют, вы можете перенаправить вывод команды и проверить код возврата.

Пример для 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

Заключение

  1. Убедитесь, что используете правильные параметры -size в команде find.
  2. -iname '*' не требуется, если вы хотите найти все файлы, так как это условие подходит под любые имена файлов.
  3. Обратите внимание на код возврата команды find, который указывает на ошибки при поиске, а не на отсутствие файлов по заданным критериям.

Следуя этим рекомендациям, вы сможете эффективно находить и обрабатывать файлы определённого минимального размера.

Оцените материал
Добавить комментарий

Капча загружается...