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