Это должно быть разрешимо с простым сценарием удара с помощью стандартных инструментов Linux:
/home/"$USER"/.gconf/apps/evolution
существует.sed
.Как насчет просто этого?
find . -type d -exec sh -c '/bin/echo -n "{}"; find "{}" -maxdepth 1 -regex ".*\." -type f | wc -l; ' \;
Вывод не является столь же сладким, но он не требует сценария, и он работает на каталоги с пробелами, а также другие неалфавитно-цифровые символы.
Вы пропускаете некоторые двойные кавычки (всегда помещаемые двойные кавычки вокруг подстановок переменных $foo
и замены команды $(foo)
, если Вы не знаете, почему Вы можете безопасно оставить их и должны оставить их). Но это не вся проблема.
if [ ! -d $START ]
должен быть if [ ! -d "$START" ]
.
DIRS=$(find "$START" -type d)
На данном этапе DIRS
содержит название каталога запуска и его подкаталогов рекурсивно, с промежуточными новыми строками. Таким образом, если у Вас есть какое-либо имя каталога, которое содержит новую строку, Вы проиграли: невозможно знать, какие новые строки прибыли из имени каталога и которые были разделителями. Если Вы знаете, что нет никаких новых строк в именах файлов, можно проанализировать вывод find
, но как Вы знали бы?
Между прочим, нормально не иметь двойные кавычки вокруг $(…)
здесь, потому что это - переменные присвоения, и замены в присвоениях неявно защищены. Однако отметьте это так же не защищен. Лучше всего для использования кавычек, если Вы не бегло говорите на сценариях оболочки и так являетесь всеми людьми, которые поддержат Ваш сценарий.export DIRS=$(…)
for d in $DIRS
Это - то, где Вы проигрываете: Вы хотите разделить $DIRS
в слова, таким образом, Вы не можете поместить двойные кавычки, но Вам нужны двойные кавычки потому что $DIRS
имеет все элементы, связанные вместе, и имена файлов в пробелах были бы разделителями при отъезде их, закрыл кавычки.
Обычно, когда Вы используете find
, необходимо заставить его вызвать команду обработки, с -exec
опция. Если у Вас нет трудных средств управления на именах файлов, не анализируйте вывод find
: это неоднозначно.
find "$START" -type d -exec sh -c '
echo "$0 directory has $(find "$0" -maxdepth 1 -regex ".*\\." -type f -printf \\n | wc -l) files whose name ends with ."
' {} \;
Отметьте снова во встроенном find
управляйте этим при парсинге вывода find
, Ваше количество будет выключено, если какое-либо имя файла будет содержать новую строку.
$d
кому: {}
и затем это все еще это не работает на подсчет новых строк. find
получает их правильно, но похоже, что его regex механизмам не нравится он, и новая строка повреждает соответствие. Используя -path "*\\."
заставляет его работать.
– lynxlynxlynx
04.07.2012, 09:58
$d
в $0
(нет {}
!, Который был бы непортативным и невозможным заключить в кавычки правильно). Я сохранил regexp, как это было в вопросе. Хм, таким образом, этот конкретный regexp действительно исключает имена файлов, содержащие новые строки, означая это -print | wc -l
на самом деле работал бы во внутреннем find
.
– Gilles 'SO- stop being evil'
04.07.2012, 10:38
{}
делает без дополнительного заключения в кавычки. Для мобильности я не вижу никакой другой путь, чем разделить его с xargs
.
– lynxlynxlynx
04.07.2012, 10:48
У Вас есть классическая ошибка заключения в кавычки. Зафиксируйте, чтобы цикл был похож на это:
for d in "$DIRS"
Кроме того, Вы могли подать его find
вывод непосредственно, например:
find "$START" -type d | while read d
do # and so on...
Как в стороне, || :
бит абсолютно избыточен с тех пор echo
всегда имеет возвращаемое значение 0.
"$DIRS"
бесполезно: for
тело цикла будет работать только однажды на конкатенации всех имен каталогов. while read d
должен быть while IFS= read -r d
, и это будет все еще дросселировать на именах каталогов, содержащих новые строки.
– Gilles 'SO- stop being evil'
04.07.2012, 03:29