Трубка find -name к xargs приводит к именам файлов с пробелами, которые не передаются команде

26

Обычно для удаления файлов с пробелами в имени файла вам нужно выполнить:

$ rm "file name"

но если я хочу удалить несколько файлов, например:

$ find . -name "*.txt" | xargs rm

Это не удалит файлы с пробелами в них.

Ashley
источник
Полное предположение здесь: find -name "*\ *.txt" | xargs rmработает ли для двух файлов слов?
Странник

Ответы:

49

Вы можете сказать findи xargsиспользовать нулевые терминаторы

find . -name "*.txt" -print0 | xargs -0 rm

или (проще) использовать встроенное -deleteдействиеfind

find . -name "*.txt" -delete

или (спасибо @kos)

find . -name "*.txt" -exec rm {} +

любой из которых должен соблюдать ARG_MAXограничения системы без необходимости xargs.

steeldriver
источник
1
Не могу дважды сказать это жестко :), так как вы упомянули, ARG_MAXя также упомяну, что find . -name "*.txt" -exec rm {} \;это будет "безопасный выстрел"
kos
3
Так говорит мастер: всегда помни xargs -0.
Джошуа
1
Супер важный момент: -print0не должно быть последний вариант (или , по крайней мере , после того, как -name "*.txt") в противном случае это будет хит файлов больше не ограничивается*.txt ...
Кев
1

Кстати, если вы использовали что-то отличное от find, вы можете использовать tr, чтобы заменить символы новой строки нулевыми байтами.

Например. следующая строка удаляет 10 последних измененных файлов в каталоге, даже если в их именах есть пробелы.

ls -tp | grep -v / | head -n 10 | tr "\n" "\0" | xargs -0 rm

Ибрагим
источник
Да, это работает.
Питер Мортенсен
0

Команда xargs по умолчанию использует в качестве разделителей табуляции, пробелы и новые строки. Вы можете указать использовать символы новой строки ('\ n') только с опцией -d:

find . -name "*.txt" | xargs -d '\n' rm

Исходный ответ на ТА .

joseph_morris
источник
Этот ответ упоминается -0вместо -d(для xargs) для систем BSD. Что использует Ubuntu? Принятый ответ здесь использует -0. Что правильно?
Питер Мортенсен