Unix: как удалить файлы, перечисленные в файле - PullRequest
71 голосов
/ 28 февраля 2011

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

Пример:

/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php

Мне нужно удалить их. Пробовал rm & # x60; cat 1.txt & # x60; и это говорит, что список слишком длинный.

Нашел эту команду, но когда я проверяю папки из списка, у некоторых из них все еще есть файлы xargs rm <1.txt Ручной вызов rm удаляет файлы из таких папок, поэтому нет проблем с разрешениями.

Ответы [ 12 ]

91 голосов
/ 28 февраля 2011

Это не очень эффективно, но будет работать, если вам нужны шаблоны глобуса (как в / var / www / *)

for f in $(cat 1.txt) ; do 
  rm "$f"
done

Если у вас нет шаблонов и вы уверены, что ваши пути в файле не содержат пробелов или других странных вещей, вы можете использовать xargs, например, так:

xargs rm < 1.txt
47 голосов
/ 23 января 2014

Предполагая, что список файлов находится в файле 1.txt, затем выполните:

xargs rm -r <1.txt

Опция -r вызывает рекурсию в любые каталоги, названные в 1.txt.

Если какие-либо файлы доступны только для чтения, используйте параметр -f для принудительного удаления:

xargs rm -rf <1.txt

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

file .txt

- это фактически два отдельных файла: file и .txt.

Это может показаться не таким опасным, но если опечатка выглядит примерно так:

myoldfiles *

Тогда вместо удаления всех файлов, которые начинаются с myoldfiles, вы в конечном итоге удалите myoldfiles и все не-точечные файлы и каталоги в текущем каталоге.Наверное, не то, что вы хотели.

14 голосов
/ 01 июня 2016

Вы можете использовать '\ n' для определения символа новой строки как разделителя.

xargs -d '\n' rm < 1.txt

Будьте осторожны с ключом -rf, потому что он может удалить то, что вам не нужно, если 1.txtсодержит пути с пробелами.Вот почему новый разделитель строк немного безопаснее.

В системах BSD вы можете использовать опцию -0, чтобы использовать символы новой строки в качестве разделителя, например:

xargs -0 rm < 1.txt
14 голосов
/ 18 февраля 2014

Используйте это:

while IFS= read -r file ; do rm -- "$file" ; done < delete.list

Если вам нужно расширение glob, вы можете опустить цитирование $file:

IFS=""
while read -r file ; do rm -- $file ; done < delete.list

Но учтите, что имена файлов могут содержать «проблемный» контент, и я бы использовал версию без кавычек. Представьте себе этот шаблон в файле

*
*/*
*/*/*

Это приведет к значительному удалению из текущего каталога! Я бы посоветовал вам подготовить список удаления таким образом, чтобы шаблоны глобуса больше не требовались, а затем использовать кавычки , как в моем первом примере.

13 голосов
/ 28 февраля 2011

xargs -I{} sh -c 'rm {}' < 1.txt должен делать то, что вы хотите.Будьте осторожны с этой командой, так как одна неправильная запись в этом файле может вызвать много проблем.

Этот ответ был отредактирован после того, как @tdavies указал, что оригинал не выполнял расширение оболочки.

12 голосов
/ 28 февраля 2011

Вы можете использовать этот однострочник:

cat 1.txt | xargs echo rm | sh

, который выполняет расширение оболочки, но выполняет rm минимальное количество раз.

4 голосов
/ 21 декабря 2017

cat 1.txt | xargs rm -f | bash Запуск команды сделает следующее только для файлов.

cat 1.txt | xargs rm -rf | bash Выполнение команды приведет к следующему рекурсивному поведению.

3 голосов
/ 22 декабря 2014

В этом конкретном случае из-за опасностей, указанных в других ответах, я бы

  1. отредактировал, например, в Vim и :%s/\s/\\\0/g, экранируя все пробелы с обратной косой чертой.*

  2. Затем :%s/^/rm -rf /, предшествующий команде.С -r вам не нужно беспокоиться о том, чтобы каталоги были перечислены после содержащихся в нем файлов, а с -f он не будет жаловаться из-за отсутствующих файлов или дублирующихся записей.

  3. Запустите все команды: $ source 1.txt

1 голос
/ 11 июня 2015

Вот еще один пример зацикливания. Этот файл также содержит оператор if в качестве примера проверки, является ли запись «файлом» (или «каталогом», например):

for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done
0 голосов
/ 07 июня 2019

Просто чтобы предоставить другой способ, вы также можете просто использовать следующую команду

$ cat to_remove
/tmp/file1
/tmp/file2
/tmp/file3
$ rm $( cat to_remove )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...