Удаление папок с пробелами в их именах с помощью xargs
Почему xargs не может удалить каталоги с пробелами в их именах и как это исправить?
76 find . -type d |xargs rm -rf
77 rm -rf fire\ hydrant/
78 rm -rf wine\ glass/
79 rm -rf tennis\ racket/
80 rm -rf traffic\ light/
81 rm -rf parking\ meter/
82 rm -rf teddy\ bear/
83 rm -rf sports\ ball/
84 rm -rf cell\ phone/
85 rm -rf stop\ sign/
86 rm -rf dining\ table/
87 rm -rf potted\ plant/
3 ответа
Исправить это с помощью -print0 в find а также xargs -0 в xargs сказать обеим командам использовать символ NULL в качестве разделителя вместо пробела:
find . -type d -print0 | xargs -0 rm -rf
Вот хорошее объяснение того, почему оно ломается и как это исправление работает из командной строки Linux Уильяма Шоттса-младшего.
Работа с забавными именами файлов
Unix-подобные системы позволяют вставлять пробелы (и даже переводы строк!) В имена файлов. Это вызывает проблемы для таких программ, как
xargsэта конструкция списков аргументов для других программ. Встроенное пространство будет рассматриваться как разделитель, а полученная команда будет интерпретировать каждое слово, разделенное пробелом, как отдельный аргумент. Чтобы преодолеть это, find и xarg разрешают необязательное использование нулевого символа в качестве разделителя аргументов. Нулевой символ определяется в ASCII как символ, представленный нулем (в отличие, например, от пробела, который определяется в ASCII как символ, представленный номером 32). Команда find предоставляет действие -print0, которое создает разделенный нулями вывод, а команда xargs имеет опцию --null, которая принимает разделенные нулями вводные данные. Вот пример:find ~ -iname '*.jpg' -print0 | xargs --null ls -lИспользуя эту технику, мы можем гарантировать, что все файлы, даже те, которые содержат встроенные пробелы в своих именах, обрабатываются правильно.
(-0 это короткая версия --null опция)
Вам не нужно xargs, find Сам может сделать это надежно с обработкой:
любой вид возможных имен файлов
без запуска
ARG_MAX
Если каталоги пусты, используйте -delete действие:
find . -type d -delete
Если не пусто, используйте rm -r в -exec действие:
find . -type d -exec rm -r {} +
Если вы настаиваете на использовании xargs для любых имен каталогов без новой строки в их именах вы можете использовать новую строку в качестве разделителя входящих аргументов:
find . -type d | xargs -d $'\n' rm -r
Лучший способ, получить файлы NUL отдельно и разобраться с этим -0 вариант xargs:
find . -type d -name 'foo bar*' -print0 | xargs -0 rm -r
Для всех rm -r б, добавить -f то есть делать rm -rf если нужно.
Чтобы специально удалить все подкаталоги с пробелами в имени, простейшей командой будет:
find . -type d -name "* *" -exec rm -rf {} +
Это тот же подход, который был предложен ранее, единственное отличие заключается в -name фильтрация.