Назад | Перейти на главную страницу

Как удалить содержимое каталога, если в пути есть пробелы?

find -name "lastStable" -o -name "lastSuccessful" -exec sh -c "sudo rm -rv {}/*" {} \; 

Как видно из приведенной выше команды, я просматриваю и удаляю содержимое lastStable и lastSuccessful каталоги, но оставив эти папки позади. Однако в find, Я могу получить пути с такими пробелами, как:

/promotions/Production Development Environment/lastStable

Как мне заставить мой сценарий поиска обрабатывать эти пути с пробелами внутри них?

Пытаться:

find . -path "*/lastSuccessful/*" -o -path "*/lastStable/*"

Если это похоже, он собирается выбрать все файлы / каталоги внутри выбранных путей.

Обратите внимание, это должно никогда выберите путь, где lastStable или lastSuccessful - это последний элемент пути к каталогу.

Затем вы можете изменить команду на

find . -path "*/lastSuccessful/*" -delete -o -path "*/lastStable/*" -delete

Что удалит все подкаталоги внутри этих путей.

Это работает, потому что -path соответствует всему пути, оценивая его как одну строку, но по-прежнему учитывает шаблоны подстановки. В -delete выполнит необходимый механизм удаления для файла, который соответствует (rmdir или unlink). Он не требует специальной обработки (пробелы и т. Д.), Потому что вы не передаете запрос оболочке (которая обычно расширяет символы, такие как пробелы или звездочки).

См. Предыдущий вопрос о unix.se: "Можно ли использовать find -exec sh -c безопасно? ".

Причина, по которой текущая попытка не удалась, заключается в том, что она заменяет совпадающий путь к файлу непосредственно в аргументе на sh -c; таким образом, если совпадающий путь к файлу - «/ promotions / Production Development Environment / lastStable», будет запущен эквивалент:

sh -c "sudo rm -rv /promotions/Production Development Environment/lastStable/*" '/promotions/Production Development Environment/lastStable'

(путь включен дважды, потому что {} встречается дважды в аргументах -exec.) Затем оболочка выполняет разбиение слов по заданной команде и запускает эквивалент:

sudo rm -rv '/promotions/Production' 'Development' 'Environment/lastStable'/*

... это совсем не то, что вы хотели.

Но обратите внимание, что второе появление {} в -exec строка не разделяется на слова, и вы можете воспользоваться этим:

find -name "lastStable" -o -name "lastSuccessful" -exec sh -c 'sudo rm -rv "$0"/*' {} \;

Обратите внимание "$0" вместо того {} (так что оболочка выполнит замену и сделает это без разделения слов), и одинарные кавычки вокруг подкоманды (так $0 не интерпретируется до передачи в оболочку). Это приводит к эквиваленту:

sh -c 'sudo rm -rv "$0"/*' '/promotions/Production Development Environment/lastStable'

а затем оболочка заменяет $0 со следующим аргументом команды оболочки, давая:

sudo rm -rv "/promotions/Production Development Environment/lastStable"/*

что (насколько я понимаю) именно то, что вам нужно.

Для тех, кто хочет знать, как мне удалось удалить содержимое папки, но сохранить папку, а также обработать пробелы, вот как я это сделал:

find $PWD -name "lastSuccessful" -o -name "lastStable" -type d -not -empty -print0 | while read -d $'\0' path; do cd "$path"; ls -1 | xargs sudo rm -fvr; done

Что он делает: находит полный путь к каталогу, который я ищу. Компакт-диски в этот каталог и перечисляет файлы, затем удаляет все эти файлы / папки.

Пытаться rm -- или используйте find -inum или подключите его к ls -i чтобы получить индекс #, тогда rm -i $inode#