it-swarm.com.ru

Unix: Как удалить файлы, перечисленные в файле

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

Пример:

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

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

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

68
Alexander

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

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

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

xargs rm < 1.txt
89
nos

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

xargs rm -r <1.txt

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

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

xargs rm -rf <1.txt

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

file .txt

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

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

myoldfiles *

Затем вместо удаления всех файлов, начинающихся с myoldfiles, вы в конечном итоге удалите myoldfiles и all non-dot-files и каталоги в текущем каталоге. Вероятно, не то, что вы хотели.

47
aks

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

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

13
Mark Drago

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

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

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

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

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

*
*/*
*/*/*

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

12
hek2mgl

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

cat 1.txt | xargs echo rm | sh

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

11
tgdavies

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

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

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

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

xargs -0 rm < 1.txt
11
Ray

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

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

4
Uzayr

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

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

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

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

2
Evgeni Sergeev

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

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

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

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

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

# 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
0
Ferroao