Как я могу рекурсивно удалять файлы, содержащие пробелы?

7728
Dr Beco

У меня возникли некоторые проблемы с этой командой под Bash в Ubuntu:

rm $(find . -name "*.exe") 

Моя цель - рекурсивно удалить все файлы, оканчивающиеся на .exe. Но некоторые файлы имеют пробелы, и это нарушает команду.

Любые предложения о том, как подойти к этой проблеме?

5

4 ответа на вопрос

16
Jonathan Leffler
find . -name "*.exe" -exec rm -f '{}' + 

Он имеет findформат команды и аргументов и тщательно избегает искажения имен (передавая каждое из них в качестве отдельного аргумента rm). «+» Означает «делай столько, сколько сможешь, разумно в одном исполнении rm».

`find (1)` имеет действие `-delete` (может быть, только GNU find), которое сохранит все подпроцессы и громоздкие параметры командной строки. найти. -name '* .exe' -delete` camh 12 лет назад 3
@camh: перейдите по ссылке на документацию POSIX; `-delete` не входит. Это в GNU `find`; вопрос для Linux; так что можно использовать `-delete`. Тем не менее, весь мир не Linux, и портативный ответ может быть полезным. Jonathan Leffler 12 лет назад 0
3
intuited

Вы можете направить вывод из findв xargs, указав, что только новые строки должны рассматриваться как разделители между именами файлов:

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

Более переносимый способ сделать это - использовать нулевой символ в качестве разделителя:

find -name '*.exe' -print0 | xargs -0 /bin/rm 

Смотрите findman-страницу для примера, который делает это.

Другой вариант - использовать команду, которую вы использовали, но установить внутренний разделитель аргументов bash только на новые строки:

IFS=$'\n'; rm $(find . -name "*.exe"); 

Здесь $'...'конструкция цитирования используется для создания символа новой строки. Этот подход будет менее устойчивым в случае длинного списка имен файлов, чем будет использовать xargs.

Нет смысла использовать что-либо, кроме параметров `-print0` и` -0`; другая не работает правильно, если имена содержат символы новой строки (и это допустимый символ в имени файла Unix). Аналогично со взломом IFS. Обратите внимание, что это специфичные для GNU (хотя и весьма разумные) расширения стандарта. Jonathan Leffler 12 лет назад 1
@Jonathan: Я обычно сам использую `-d` только потому, что он меньше печатает, и на практике имена файлов (по крайней мере, для меня) никогда не содержат перевода строки. Есть также преимущество, заключающееся в том, что вы можете фильтровать вывод `find` через другие программы (grep, tail и т. Д.) Перед отправкой его в` xargs`. intuited 12 лет назад 0
1
mainzelM

Simply pass the -delete option to find:

find . -name "*.exe" -delete 

This saves you from quoting and any other filename hassles and is presumably faster than -exec because no new processes need to be spawned.

0

Вам может помочь экранирование персонажей вручную.

find . -name "*.exe" | sed -s 's/\ /\\ /' | xargs rm -f 
Не надежная техника; кроме всего прочего, `xargs` разделяет имена на пробелы. Вы можете использовать `найти. -имя "* .exe" -print0 | xargs -0 rm -f`, где `-print0` оканчивает имена файлов ASCII NUL, а` -0` означает, что `xargs` читает имена, оканчивающиеся на ASCII NUL. Обратите внимание, что это специфичные для GNU (хотя и весьма разумные) расширения стандарта. Jonathan Leffler 12 лет назад 0
@Jonathan Правда .. Ваш ответ определенно лучше. 12 лет назад 0

Похожие вопросы