Suppression interactive de fichiers d'une liste

12

Je souhaite supprimer une liste de fichiers et demander une confirmation. La liste est dans le list.txtfichier. Pourquoi la commande suivante ne fonctionne pas correctement?

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

La commande précédente ne m'attend pas mais heureusement aucun fichier n'est supprimé.

J'utilise Bash.

Francesco Turco
la source

Réponses:

19

rm -ilit sa réponse à partir de l'entrée standard, dont il hérite de la whileboucle. Donc, une ligne de texte list.txtest utilisée comme réponse à la question "vraiment supprimer?" question. Pour résoudre ce problème, vous devrez séparer les deux sources d'entrée. Le moyen le plus simple consiste à readprendre son entrée à partir d'un descripteur de fichier distinct:

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

Vous ne redirigez plus l'entrée standard (fd 0) pour la boucle while, vous rmlirez donc à partir du terminal comme vous le souhaitez.

Alternativement, vous auriez pu faire:

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

Ou, avec GNU xargs:

xargs -rd '\n' --arg-file=list.txt rm -i --
chepner
la source
1
Donc, si j'avais dans la liste un fichier nommé y, le fichier précédent aurait été supprimé?
Francesco Turco
5
Pas seulement y, mais tout nom commençant par y. Apparemment, il rmsuffit de regarder le premier caractère de la réponse qu'il reçoit: «y» est oui, tout le reste est non.
chepner
1

Pour quelque chose d'un peu plus fantaisiste que de répondre oui ou non à chaque fichier, vous pouvez utiliser iselectpour une sélection interactive basée sur ncurses. par exemple

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

ou pour permettre la sélection de fichiers dans le répertoire courant:

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

Cela affichera une liste basée sur ncurses en plein écran (terminal complet), où les fichiers peuvent être sélectionnés et désélectionnés à volonté en appuyant sur ESPACE. appuyez sur ENTER pour accepter vos sélections (les entrées sélectionnées seront imprimées sur stdout), ou qpour quitter (rien imprimé sur stdout). appuyez hpour obtenir de l'aide.

Notez le echo rm- je l'ai écrit comme ça pour les tests. changez-le juste rmune fois que vous êtes sûr de comprendre ce qu'il fait.

Notez également qu'il xargsest utilisé ici avec \ncomme séparateur d'entrée. Cela ne fonctionnera pas si l'un des noms de fichiers contient des caractères de saut de ligne. D'ailleurs, le iselectne fonctionnera pas correctement non plus - il attend un élément par ligne - malheureusement, iselectn'a pas d'option pour une entrée ou une sortie à terminaison nulle.

iselectest empaqueté pour debian, probablement ubuntu et d'autres distributions aussi. la page d'accueil est à http://www.ossp.org/pkg/tool/iselect/

cas
la source