Как легко удалить файлы в списке путей?

У меня есть список строк, как

/usr/lib/i386-linux-gnu/libavfilter.so
/usr/lib/i386-linux-gnu/libavfilter.so.3
/usr/lib/i386-linux-gnu/libavfilter.so.3.42.103
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3.42.103
/usr/local/lib/libavfilter.so
/usr/local/lib/libavfilter.so.4
/usr/local/lib/libavfilter.so.4.4.100

Как я могу удалить эти файлы в целом, а не удалять их по одному, как

 rm        /usr/lib/i386-linux-gnu/libavfilter.so
 rm        /usr/lib/i386-linux-gnu/libavfilter.so.3
 rm        /usr/lib/i386-linux-gnu/libavfilter.so.3.42.103
 rm        /usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so
 rm        /usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3
 rm        /usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3.42.103
 rm        /usr/local/lib/libavfilter.so
 rm        /usr/local/lib/libavfilter.so.4
 rm        /usr/local/lib/libavfilter.so.4.4.100

?

ПРЕДУПРЕЖДЕНИЕ!Не применяйте команды ниже, не проверяя вывод

6 ответов

Решение

Каков ваш вклад? Файл? Команда? В любом случае, xargs должно быть полезно:

cat file | xargs rm

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

В качестве альтернативы используйте xargs --arg-file="file.txt" rm, Это экономит на трубе и ненужной кошке.

Если вы хотите сделать больше с каждой строкой, вы можете использовать традиционный цикл bash:

# uses echo for testing
# remove # before rm for actual deletion
while read -r path; do
    echo "deleting $path"
    # rm "$path"
done < file

Если ваш список является выводом findу вас есть еще пара вариантов, в том числе -delete вариант или использование -exec rm {} \+, Есть почти наверняка несколько десятков других жизнеспособных путей к успеху. Если вы делаете автоматическое удаление с помощью find, просто проверьте вывод перед удалением. Это не простит вам ваших ошибок.

Пробелы могут быть проблемой с передачей вещей в xargs, Это не может быть проблемой для вас и вашего местонахождения, но оба locate а также xargs есть способ обойти это. Они оба могут использовать \0 нулевой символ в качестве разделителя вместо строк возврата. Ура. Короче говоря, ваша команда становится:

locate -0b libavfilter.so | xargs -0 rm

Передайте вывод xargs:

echo "/usr/lib/i386-linux-gnu/libavfilter.so
/usr/lib/i386-linux-gnu/libavfilter.so.3
/usr/lib/i386-linux-gnu/libavfilter.so.3.42.103
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3
/usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3.42.103
/usr/local/lib/libavfilter.so
/usr/local/lib/libavfilter.so.4
/usr/local/lib/libavfilter.so.4.4.100" | xargs rm

Или, если ваш список находится в файле:

cat file | xargs rm

На самом базовом уровне это можно сделать в Python:

import os

with open('input.txt') as f:
    for line in f:
        os.unlink(line.strip())

Если у вас есть экзотические имена файлов (например, созданные с touch with$'\n'backslash или же with$'\n'newline, что очень плохая идея, но возможно) вы можете использовать входной файл так:

./with\backspace
./with\nnewline

И обрабатывать все в Python 3 так:

import os

with open('./input.txt') as f:
    for l in f:
        # alternatively one can use 
        # bytes(l.strip(),sys.getdefaultencoding())
        bytes_filename =  bytes(l.strip(), 'utf-8').decode('unicode_escape')
        f_stat = os.stat(os.fsdecode( bytes_filename ) )
        print(l.strip(),f_stat)

Есть способ сделать это и в Python 2.

Вы можете поместить файлы после друг друга, разделенные пробелом. Вот так:

rm /usr/lib/i386-linux-gnu/libavfilter.so /usr/lib/i386-linux-gnu/libavfilter.so.3 /usr/lib/i386-linux-gnu/libavfilter.so.3.42.103        /usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so /usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3 /usr/lib/i386-linux-gnu/i686/cmov/libavfilter.so.3.42.103 /usr/local/lib/libavfilter.so /usr/local/lib/libavfilter.so.4 /usr/local/lib/libavfilter.so.4.4.100

Самый простой способ

cat list.txt | xargs -P 3 rm 

Хотя вы не можете использовать -P, который по умолчанию будет запускать как можно больше, но это может быть проблемой, если ваш список велик. Смотрите man- страницы для дальнейшего объяснения.

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

cat list.txt | xargs -d '\n' -P 3 rm 

В Mac OS это приведет к ошибке, но вы не в Mac OS, так что вы можете использовать это.

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

Используйте что-то вроде notepad++, перейдите на замену (ctrl+r), введите -> find what: \r\n (убедитесь, что режим поиска установлен в расширенный режим) и замените на: введите пробел

тогда у вас все в очереди

скопируйте его в оболочку и введите rm -rf [вставить файл /foldernames из notepad ++ здесь]

Другие вопросы по тегам