Script с ошибками пробелов в именах каталогов

У меня очень простой вопрос, я нашел кучу ответов на подобные вопросы, но никто не решил это для меня.

У меня есть оболочка script, которая проходит через каталог и выводит количество файлов и каталогов в подкаталоге, за которым следует имя каталога.

Однако он не работает с каталогами с пробелами, он пытается использовать каждое слово в качестве нового аргумента. Я попытался поставить $dir в котировках, но это не помогает. Возможно, потому, что он уже включен в эхо-котировки.

for dir in `find . -mindepth 1 -maxdepth 1 -type d`
do
    echo -e "`ls -1 $dir | wc -l`\t$dir"
done

Заранее благодарим за помощь:)

Ответ 1

Предупреждение. Два из трех примеров кода ниже используют bashisms. Пожалуйста, позаботьтесь, чтобы использовать правильный, если вам нужен POSIX sh, а не bash.


Не делай ничего из этого. Если ваша реальная проблема связана с использованием find, вы можете использовать ее так:

shopt -s nullglob
while IFS='' read -r -d '' dir; do
  files=( "$dir"/* )
  printf '%s\t%s\n' "${#files[@]}" "$dir"
done < <(find . -mindepth 1 -maxdepth 1 -type d -print0)

Однако для итерации только под непосредственными подкаталогами вам совсем не нужно найти:

shopt -s nullglob
for dir in */; do
  files=( "$dir"/* )
  printf '%s\t%s\n' "${#files[@]}" "$dir"
done

Если вы пытаетесь сделать это способом, совместимым с POSIX sh, вы можете попробовать следующее:

for dir in */; do
  [ "$dir" = "*/" ] && continue
  set -- "$dir"/*
  [ "$#" -eq 1 ] && [ "$1" = "$dir/*" ] && continue
  printf '%s\t%s\n' "$#" "$dir"
done

Вы не должны использовать ls в скриптах: http://mywiki.wooledge.org/ParsingLs

Вы не должны использовать for для чтения строк: http://mywiki.wooledge.org/DontReadLinesWithFor

Используйте массивы и глобы при подсчете файлов, чтобы сделать это безопасно, надежно и без внешних команд: http://mywiki.wooledge.org/BashFAQ/004

Всегда NUL-завершать списки файлов, выходящие из find - в противном случае имена файлов, содержащие новые строки (да, они законны в UNIX!), могут вызывать одно имя для чтения как несколько файлов или (в некоторых найти версии и обычаи) ваше "имя файла" не соответствует реальному имени файла. http://mywiki.wooledge.org/UsingFind