So löschen Sie in einer Textdatei aufgelistete Dateien

23

Ich habe eine Textdatei, die eine Liste von Pfaden zu verschiedenen Dateien enthält. Gibt es einen Befehl, mit dem ich jede Zeile durchlaufen und die Datei unter dem angegebenen Pfad löschen kann?

daka
quelle

Antworten:

33

Verwendung xargs:

xargs rm < file  # or
xargs -a file rm

Dies funktioniert jedoch nicht, wenn die Dateinamen / -pfade Zeichen enthalten, die maskiert werden sollen.

Wenn Ihre Dateinamen keine Zeilenumbrüche enthalten, haben Sie folgende Möglichkeiten:

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

Alternativ können Sie das folgende Skript erstellen:

#!/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"

Speichern unter /usr/local/bin/delete-from, Ausführungserlaubnis erteilen:

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

Dann starte es mit:

delete-from /path/to/file/with/list/of/files
Eric Carvalho
quelle
2
Wirklich saubere Antwort, aber catnicht erforderlich, können Sie stdinUmleitung verwenden:< file xargs rm
Kos
Die Namen der Ordner werden aufgeteilt und dann gesucht. ZB wird MEIN ORDNER als "MEIN" und "ORDNER" interpretiert?
Daka
@sudoman Antwort aktualisiert.
Eric Carvalho
Wenn die Dateien keine Leerzeichen enthalten, können Sie einfach "rm - $ (cat file)" in bash oder "rm - cat file" in (ba) sh oder csh eingeben.
shooper
@shooper catist ungewöhnlich, wie gerade gesagt, nutzen Sie aus stdin! Schauen Sie sich seine aktualisierte Antwort an
kos
20

Hier ist eine Möglichkeit, mit Dateinamen mit Leerzeichen, Backslashes und anderen seltsamen Zeichen umzugehen:

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

Damit wird jede Zeile von gelesen list.txt, gespeichert $fileund ausgeführt rm. Das -rstellt sicher, dass Backslashes wörtlich gelesen werden (so dass \ta \und a tund nicht ein TAB übereinstimmen ). Das --stellt sicher, dass es sich auch um Dateinamen handelt, die mit beginnen -.

Sie können dies auch in Perl tun:

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

Dieser liest jeden Dateinamen in den %kHash ein und unlinklöscht dann jeden von ihnen.

terdon
quelle
10

Durch Python.

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

Speichern Sie das obige Skript in einer Datei mit dem Namen "like" script.pyund führen Sie das Skript aus, indem Sie den folgenden Befehl auf dem Terminal ausführen.

python3 script.py file

file ist eine Eingabedatei, in der der Pfad der Dateien gespeichert ist, die Sie tatsächlich entfernen möchten.

Avinash Raj
quelle
6
Ah, zumindest haben Sie den Mut, eine Python-Antwort zu posten :)
Jacob Vlijm
3

Dumm, aber hier ist einer:

 tar -cvf /dev/null --remove-files -T filename
shooper
quelle
2

Ein anderer Weg dies zu tun:

Sie können die Datei vorbereiten, indem Sie sie zu einem Shell-Skript machen:

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

Wenn Ihre Dateinamen möglicherweise ein einfaches Anführungszeichen ( ') enthalten, können Sie diese leicht erweiterte Version verwenden, um sie zuerst zu maskieren:

$ 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'\'''

Und Sie können dies ausführen, indem Sie es weiterleiten an sh:

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

Soweit ich weiß, haben Sie eine Textdatei mit den Dateien mit den vollständigen Pfaden. Es gibt zwei Möglichkeiten:

  1. In Ihrer Liste sind die Dateinamen durch Zeilenumbrüche getrennt, dh jede Zeile enthält den vollständigen Pfad zu einer Datei. In diesem Fall: Hier ist ein einfacher Ausweg:

    for i in $(cat listOfFiles.txt); do
        rm -f $i
    done
    
  2. Wenn Ihre Liste eine oder mehrere Zeilen mit Dateinamen enthält, die durch Leerzeichen oder Tabulatoren getrennt sind, finden Sie hier den Drill:

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

    Dadurch werden alle Leerzeichen in Zeilenumbrüche umgewandelt

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

Ja, es gibt viele Möglichkeiten, dies zu erreichen, aber dies ist ein sehr einfacher Ansatz.

Hopfender Hase
quelle