Ваша основная ошибка: вы parsing ls
!
Если вы хотите, чтобы найти (обычные файлы), которые являются пустыми, и если у вас есть версия find
, которая поддерживает -empty
предикат, использовать его:
find . -type f -empty
Обратите внимание, что это будет рекурсию во вложенных папках тоже; если вы не хотите этого, используйте:
find . -maxdepth 1 -type f -empty
(при условии, что ваш find
также поддерживает -maxdepth
).
Если вы хотите, чтобы подсчитать, сколько пустой (регулярные) файлы у вас есть:
find . -maxdepth 1 -type f -empty -printf x | wc -m
и если вы хотите, чтобы выполнять обе операции одновременно, то есть напечатать имя или сохранить их в массив для дальнейшего использования, и сосчитать их:
empty_files=()
while IFS= read -r -d '' f; do
empty_files+=("$f")
done < <(find . -maxdepth 1 -type f -empty -print0)
printf 'There are %d empty files:\n' "${#empty_files[@]}"
printf ' %s\n' "${empty_files[@]}"
с Bash≥4.4, вы могли бы использовать mapfile
вместо while
- петли read
:
mapfile -t -d '' empty_files < <(find . -maxdepth 1 -type f -empty -print0)
printf 'There are %d empty files:\n' "${#empty_files[@]}"
printf ' %s\n' "${empty_files[@]}"
Для POSIX-совместимый способ, использовать test
с -s
вариант:
find . -type f \! -exec test -s {} \; -print
и если вы не хотите рекурсию подкаталогов, вам придется -prune
им:
find . \! -name . -prune -type f \! -exec test -s {} \; -print
и если вы хотите, чтобы сосчитать их:
find . \! -name . -prune -type f \! -exec test -s {} \; -exec printf x | wc -m
и здесь, если вы хотите выполнить обе операции (считать их и сохранить их в массиве для дальнейшего использования), используйте предыдущую while
- read
цикл (или mapfile
, если вы живете в будущем) с этим find
:
find . \! -name . -prune -type f \! -exec test -s {} \; -exec printf '%s\0' {} \;
Также см chepner's answer для чистого раствора оболочки (нуждается в незначительной настройке, чтобы быть POSIX-совместимой).
Относительно Ваш комментарий
Я хочу, чтобы считать и удалить [пустые файлы]. Как я могу это сделать одновременно?
Если у вас есть GNU find
(или find
, который поддерживает все лакомства):
find . -maxdepth 1 -type f -empty -printf x -delete | wc -m
если нет,
find . \! -name . -prune -type f \! -exec test -s {} \; -printf x -exec rm {} \; | wc -m
Убедитесь, что -delete
(или -exec rm {} \;
) предикат в конце! не меняйте порядок предикатов!
[Не анализировать выходные данные 'ls'] (http://mywiki.wooledge.org/ParsingLs). –
Я не знаю другого использования. Ls неправда? @gniourf_gniourf – esrtr
@lurker Даже это не рекомендуется, потому что количество строк вывода - это не количество файлов, если имена файлов содержат новую строку. – chepner