Хорошо, давайте делать это постепенно.
И давайте предположим, что вы на самом деле действительно хотите выглядеть в подкаталогах, а также, несмотря на то, что это только подразумевается в вашем вопросе.
В качестве первого прохода, это просто простое упражнение: передать подстановочный знак 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