Удаление папок с пробелами в их именах с помощью 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 фильтрация.

Другие вопросы по тегам