Подтвердить что ты не робот

Unix: удаление файлов, перечисленных в файле

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

Пример:

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

I need delete them. Tried rm `cat 1.txt` and it says the list is too long.

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

4b9b3361

Ответ 1

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

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

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

xargs rm < 1.txt

Ответ 2

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

xargs rm -r <1.txt

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

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

xargs rm -rf <1.txt

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

file .txt

на самом деле два отдельных файла: file и .txt.

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

myoldfiles *

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

Ответ 3

Использовать этот:

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

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

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

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

*
*/*
*/*/*

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

Ответ 4

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

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

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

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

xargs -0 rm < 1.txt

Ответ 5

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

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

Ответ 6

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

cat 1.txt | xargs echo rm | sh

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

Ответ 7

cat 1.txt | xargs rm -f | bash Выполнить команду будет делать только для файлов.

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

Ответ 8

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

  • Изменить, например. Vim и :%s/\s/\\\0/g, экранируя все пробельные символы с помощью обратного слэша.

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

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

Ответ 9

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

for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done

Ответ 10

Здесь вы можете использовать набор папок из deleteelist.txt, а избегать некоторых шаблонов, а также

foreach f (cat deletelist.txt)
    rm -rf ls | egrep -v "needthisfile|*.cpp|*.h"
end

Ответ 11

Это позволит именам файлов иметь пробелы (воспроизводимый пример).

# Select files of interest, here, only text files for ex.
find -type f -exec file {} \; > findresult.txt
grep ": ASCII text$" findresult.txt > textfiles.txt
# leave only the path to the file removing suffix and prefix
sed -i -e 's/:.*$//' textfiles.txt
sed -i -e 's/\.\///' textfiles.txt

#write a script that deletes the files in textfiles.txt
IFS_backup=$IFS
IFS=$(echo "\n\b")
for f in $(cat textfiles.txt); 
do 
rm "$f"; 
done
IFS=$IFS_backup

# save script as "some.sh" and run: sh some.sh

Ответ 12

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

$ cat to_remove
/tmp/file1
/tmp/file2
/tmp/file3
$ rm $( cat to_remove )