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

1025

не могу удалить свой вопрос, вместо этого перезаписать

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

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

1
JdeBP

Хорошо, давайте делать это постепенно.

И давайте предположим, что вы на самом деле действительно хотите выглядеть в подкаталогах, а также, несмотря на то, что это только подразумевается в вашем вопросе.

В качестве первого прохода, это просто простое упражнение: передать подстановочный знак findкоманде, не забывая процитировать ее, и выполнить rmкоманду для каждого найденного файла:

find $BASE_DIR/ -name '* *' -exec rm {} \; 

Но, конечно, это ужасно неэффективно. Он запускает целый rmпроцесс для каждого отдельного файла. Поэтому, хотя мы могли бы сделать небольшой обход \+, это не то, чем мы собираемся закончить, поэтому давайте выберем более короткий путь и введем, xargsчтобы объединить имена файлов в группы:

find $BASE_DIR/ -name '* *' -print | xargs rm 

Но у этого есть две дыры в безопасности. Во-первых, если какое-либо найденное имя файла начинается со знака минус rm, оно будет рассматриваться как параметр командной строки, а не как имя файла, и генерирует ошибку. (В -exec rm {}версии также есть эта проблема.) Во-вторых xargs, как вы заметили, имена файлов, содержащие пробелы, не будут обрабатываться должным образом . Таким образом, дальнейшая итерация должна сделать это немного более пуленепробиваемым:

find $BASE_DIR/ -name '* *' -print0 | xargs -0 rm -- 

И, конечно, есть интерактивные функции, rmкоторые вы, вероятно, не хотите:

find $BASE_DIR/ -name '* *' -print0 | xargs -0 rm -f -- 

-print0И -0варианты не являются стандартными, но GNU findи xargs, а также FreeBSD findи xargs, понимать их. Однако даже это немыслимо. Нам не нужно создавать никаких дополнительных процессов вообще. GNU и FreeBSD findмогут вызывать unlink(2)системный вызов напрямую:

find $BASE_DIR/ -name '* *' -delete 

В качестве последней меры предосторожности, которая помешает вам делать больше, чем вы предполагали в определенных обстоятельствах, помните, что файловая система может содержать не только обычные файлы:

find $BASE_DIR/ -name '* *' -type f -delete 
… Так в основном то, что я написал;) Хорошее объяснение, хотя я бы порекомендовал поместить наиболее безопасный вариант в * верх * сообщения, а не внизу. slhck 10 лет назад 0
Нет: то, что ** I ** написал, еще 2014-01-09, отслеживая разницу символов _1 в вопросе_ и небольшие изменения, необходимые для оболочки C. JdeBP 10 лет назад 0
Правда, я только что увидел, что тоже ответил на это. Какой тип делает его дубликатом, тем более что ответ точно такой же, просто поменяйте местами один символ. slhck 10 лет назад 0
Интересно, почему вы не отметили его как дубликат? Я воздержался от этого, думая, что у тебя, должно быть, были свои причины. Я чуть не поставил «Дублирующий вопрос, поэтому дублирующий ответ». на самом верху. (-: JdeBP 10 лет назад 0
0
9mjb

Что случилось с

rm *\ * 

или же

rm *' '* 

или же

rm *" "* 

Вы можете попробовать «ls» перед «rm», чтобы быть уверенным в том, что вы делаете.

Это не рекурсивно, возможно, именно поэтому ОП не использовал `rm`. (Не то чтобы это нельзя было сделать, но…) slhck 10 лет назад 0

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