Як видалити файли, перелічені в текстовому файлі


23

У мене є текстовий файл, у якому є список шляхів до різних файлів. Чи є команда, яку я можу використовувати, яка буде повторювати кожен рядок і видаляти файл у вказаному шляху?

Відповіді:


33

Використання xargs:

xargs rm < file  # or
xargs -a file rm

Але це не спрацює, якщо назви файлів / шляхи містять символи, яким слід уникати.

Якщо у ваших іменах файлів немає нових рядків, ви можете:

tr '\n' '\0' < file | xargs -0 rm # or
xargs -a file -I{} rm {}

Крім того, ви можете створити такий сценарій:

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "Usage: $(basename $0) FILE\n"
    exit 1
fi

if [ ! -e "$1" ]; then
    echo -e "$1: File doesn't exist.\n"
    exit 1
fi

while read -r line; do
    [ -n "$line" ] && rm -- "$line"
done < "$1"

Збережіть це як /usr/local/bin/delete-from, надайте йому дозвіл на виконання:

sudo chmod +x /usr/local/bin/delete-from

Потім запустіть його:

delete-from /path/to/file/with/list/of/files

2
Дійсно чиста відповідь, але catвона не потрібна, ви можете скористатися stdinперенаправленням:< file xargs rm
kos

Розбиття назв папок вгору, а потім їх пошук. Наприклад, "МОЯ ФАПКА" трактується як "МОЙ" і "ФАКЛА"?
дака

@sudoman Відповідь оновлено.
Ерік Карвальо

Якщо у файлах немає пробілів, ви можете просто "rm - $ (файл cat)" в bash або "rm - cat file" в (ba) sh або csh.
стрілець

@shooper невикорисний cat, як тільки було зазначено, скористайтеся з цього stdin! Подивіться на його оновлену відповідь
kos

20

Ось один із способів роботи з іменами файлів з пробілом, зворотними косими рисами та іншими дивними символами:

while read -r file; do rm -- "$file"; done < list.txt

Це прочитає кожен рядок list.txt, збереже його як $fileі запустіть rmйого. У -rгарантує , що зворотні косі читаються буквально (так що \tвідповідає \і , tа не TAB). У --гарантує , що вона також має справу з іменами файлів , починаючи з -.

Ви також можете зробити це в Perl:

perl -lne '$k{$_}++; END{unlink for keys(%k)}' list.txt

Цей читає кожне ім'я файлу в %kхеш, а потім використовує unlinkдля видалення кожного з них.


10

Через пітон.

import sys
import os
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        os.remove(line.rstrip('\n'))

Збережіть вищевказаний скрипт у файлі з іменем «like» script.pyта виконайте його, запустивши команду нижче на терміналі.

python3 script.py file

file - це вхідний файл, де зберігається шлях до файлів, які ви насправді хочете видалити.


6
Ах, принаймні у вас є сміливість опублікувати відповідь пітона :)
Яків Влійм


2

Ще один спосіб зробити це:

Ви можете «підготувати» файл, зробивши його сценарієм оболонки:

$ sed -E "s/^(.*)$/rm '\1'/" input_file
rm 'file1'
rm 'file2'
rm 'file with some spaces.ext'

Якщо у ваших імен файлів може бути одна цитата ( '), ви можете скористатися цією розширеною версією, щоб уникнути їх спочатку:

$ sed -E "s/'/'\\\''; s/^(.*)$/rm '\1'/" input_file
rm 'file1'
rm 'file2'
rm 'file with some spaces.ext'
rm 'a file with "quotes"'
rm 'a file with '\''quotes'\'''

І ви можете запустити це, переклавши його на sh:

$ sed -E "s/'/'\\\''; s/^(.*)$/rm '\1'/" input_file | sh

1

Як я розумію, у вас є текстовий файл з файлами з повними шляхами. Є дві можливості:

  1. У вашому списку назви файлів розділені новими рядками, тобто кожен рядок має повний шлях до файлу. у цьому випадку: ось простий вихід:

    for i in $(cat listOfFiles.txt); do
        rm -f $i
    done
    
  2. Якщо у вашому списку є один або декілька рядків імен файлів, розділених пробілами чи вкладками, то тут ви знайдете підсумок:

    sed -i 's/\s\+/\n/g' listOfFiles.txt
    

    це перетворить всі пробіли в нові рядки

    for i in $(cat listOfFiles.txt); do
        rm -f $i
    done
    

Так, існує багато способів, як це зробити, але це дуже простий підхід.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.