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#