Сценарий завершается с пробелами в именах каталогов
У меня очень простой вопрос, я нашел несколько похожих ответов, но ни один из них не решил для меня.
У меня есть сценарий оболочки, который проходит через каталог и распечатывает количество файлов и каталогов в подкаталоге, а затем имя каталога.
Однако он не работает с каталогами с пробелами, он пытается использовать каждое слово в качестве нового аргумента. Я пытался поместить $ dir в цитаты, но это не помогает. Возможно, потому что это уже в эхо-цитатах.
for dir in `find . -mindepth 1 -maxdepth 1 -type d`
do
echo -e "`ls -1 $dir | wc -l`\t$dir"
done
Заранее спасибо за помощь:)
1 ответ
Предупреждение: в двух из трех приведенных ниже примеров кода используются ошибки. Пожалуйста, позаботьтесь о том, чтобы использовать правильный, если вам нужен 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