Interaktives Löschen von Dateien aus einer Liste

12

Ich möchte eine Liste von Dateien entfernen und um Bestätigung gebeten werden. Die Liste befindet sich in der list.txtDatei. Warum funktioniert der folgende Befehl nicht richtig?

while read i; do rm -i $i; done < list.txt

Der vorherige Befehl wartet nicht auf mich, aber zum Glück wird keine Datei gelöscht.

Ich benutze Bash.

Francesco Turco
quelle

Antworten:

19

rm -iLiest seine Antwort von der Standardeingabe, die es von der whileSchleife erbt . Also wird eine Textzeile von list.txtals Antwort auf das "wirklich entfernen?" Frage. Um dies zu beheben, müssen Sie die beiden Eingabequellen trennen. Der einfachste Weg ist read, seine Eingabe von einem separaten Dateideskriptor zu erhalten:

while IFS= read <&3 -r i; do
  rm -i -- "$i"     # Quote the file name, not just to be safe,
                    # but because it's the right syntax.
done 3< list.txt

Sie leiten die Standardeingabe (fd 0) für die while-Schleife nicht mehr um, sondern rmlesen wie gewünscht vom Terminal.

Alternativ hätten Sie Folgendes tun können:

IFS=$'\n' # set field separator to newline
set -f    # disable globbing upon command substitution
rm -i -- $(cat list.txt)

Oder mit GNU xargs:

xargs -rd '\n' --arg-file=list.txt rm -i --
chepner
quelle
1
Wenn ich also in der Liste eine Datei mit dem Namen hätte y, wäre die vorherige Datei gelöscht worden?
Francesco Turco
5
Nicht nur y, sondern jeder Name, der mit ... beginnt y. Anscheinend wird rmnur das erste Zeichen der empfangenen Antwort betrachtet: 'y' ist ja, alles andere ist nein.
Chepner
1

Für etwas, das etwas ausgefallener ist, als Ja oder Nein auf jede Datei zu antworten, können Sie die Option iselectfür die interaktive Auswahl auf der Basis von ncurses verwenden. z.B

iselect -a -m < list.txt | xargs -d '\n' -r echo rm 

oder um die Auswahl von Dateien im aktuellen Verzeichnis zuzulassen:

find . -maxdepth 1 -type f | iselect -a -m | xargs -d '\n' -r echo rm

Daraufhin wird eine auf Vollbildschirm (Vollterminal) basierende Auflistung angezeigt, in der Dateien durch Drücken der LEERTASTE nach Belieben ausgewählt und abgewählt werden können. Drücken Sie die EINGABETASTE, um Ihre Auswahl zu bestätigen (ausgewählte Einträge werden auf stdout gedruckt) oder um qzu beenden (nichts wird auf stdout gedruckt). Drücken Sie hfür Hilfe.

Beachten Sie die echo rm- ich habe es zum Testen so geschrieben. Ändern Sie es, rmsobald Sie sicher sind, dass Sie verstehen, was es tut.

Beachten Sie auch, xargsdass hier \nals Eingangstrennzeichen verwendet wird. Dies funktioniert nicht, wenn einer der Dateinamen Zeilenvorschubzeichen enthält. Im iselectÜbrigen funktioniert das auch nicht richtig - es erwartet ein Element pro Zeile - leider iselectgibt es keine Option für nullterminierte Eingaben oder Ausgaben.

iselectist für Debian, wahrscheinlich Ubuntu und andere Distributionen ebenfalls gepackt. Die Homepage befindet sich unter http://www.ossp.org/pkg/tool/iselect/

cas
quelle