Ошибка в Сценарии. Находка команды пропускает папки с пробелом

Это должно быть разрешимо с простым сценарием удара с помощью стандартных инструментов Linux:

  1. Проверьте если папка /home/"$USER"/.gconf/apps/evolution существует.
  2. Если это не существует, скопируйте шаблонный каталог.
  3. Замените заполнителей sed.
1
03.07.2012, 21:46
3 ответа

Как насчет просто этого?

find . -type d -exec sh -c '/bin/echo -n "{}"; find "{}" -maxdepth 1 -regex ".*\." -type f | wc -l; ' \;

Вывод не является столь же сладким, но он не требует сценария, и он работает на каталоги с пробелами, а также другие неалфавитно-цифровые символы.

1
27.01.2020, 23:54
  • 1
    за исключением новых строк, посмотрите ниже. –  lynxlynxlynx 04.07.2012, 11:04

Вы пропускаете некоторые двойные кавычки (всегда помещаемые двойные кавычки вокруг подстановок переменных $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, Ваше количество будет выключено, если какое-либо имя файла будет содержать новую строку.

2
27.01.2020, 23:54
  • 1
    Последняя команда не будет работать, хотя, так как Вы забыли изменяться $d кому: {} и затем это все еще это не работает на подсчет новых строк. find получает их правильно, но похоже, что его regex механизмам не нравится он, и новая строка повреждает соответствие. Используя -path "*\\." заставляет его работать. –  lynxlynxlynx 04.07.2012, 09:58
  • 2
    @lynxlynxlynx, Который был Пасто копии, спасибо, я забыл изменяться $d в $0 (нет {}!, Который был бы непортативным и невозможным заключить в кавычки правильно). Я сохранил regexp, как это было в вопросе. Хм, таким образом, этот конкретный regexp действительно исключает имена файлов, содержащие новые строки, означая это -print | wc -l на самом деле работал бы во внутреннем find. –  Gilles 'SO- stop being evil' 04.07.2012, 10:38
  • 3
    Не работает на меня, в то время как {} делает без дополнительного заключения в кавычки. Для мобильности я не вижу никакой другой путь, чем разделить его с xargs. –  lynxlynxlynx 04.07.2012, 10:48
  • 4
    @lynxlynxlynx Удостоверяется, что Вы скопировали правильно. Я протестировал его, и количества вышли право. Какую ошибку Вы наблюдаете? –  Gilles 'SO- stop being evil' 04.07.2012, 11:16
  • 5
    это возвращает 0, значит мою newlined папку. –  lynxlynxlynx 04.07.2012, 11:24

У Вас есть классическая ошибка заключения в кавычки. Зафиксируйте, чтобы цикл был похож на это:

for d in "$DIRS"

Кроме того, Вы могли подать его findвывод непосредственно, например:

find "$START" -type d | while read d
do # and so on...

Как в стороне, || : бит абсолютно избыточен с тех пор echo всегда имеет возвращаемое значение 0.

-2
27.01.2020, 23:54
  • 1
    "$DIRS" бесполезно: for тело цикла будет работать только однажды на конкатенации всех имен каталогов. while read d должен быть while IFS= read -r d, и это будет все еще дросселировать на именах каталогов, содержащих новые строки. –  Gilles 'SO- stop being evil' 04.07.2012, 03:29
  • 2
    хорошая выгода и кажется, что читает, не может взять '\0-d$'. –  lynxlynxlynx 04.07.2012, 09:38
  • 3
    Большинство оболочек не может обработать нулевые символы. Zsh может, и иметь много других преимуществ кроме того, но он редко устанавливается по умолчанию. –  Gilles 'SO- stop being evil' 04.07.2012, 10:39

Теги

Похожие вопросы