Eliminazione interattiva di file da un elenco


12

Vorrei rimuovere un elenco di file e chiedere conferma. L'elenco è nel list.txtfile. Perché il seguente comando non funziona correttamente?

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

Il comando precedente non mi aspetta ma fortunatamente nessun file viene eliminato.

Sto usando Bash.

Risposte:


19

rm -ilegge la sua risposta dallo standard input, che eredita dal whileloop. Quindi una riga di testo list.txtviene utilizzata come risposta al "veramente rimuovere?" domanda. Per risolvere, dovrai separare le due fonti di input. Il modo più semplice è quello di avere readil suo input da un descrittore di file separato:

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

Non stai più reindirizzando l'input standard (fd 0) per il ciclo while, quindi rmleggerai dal terminale come desideri.

In alternativa, avresti potuto fare:

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

Oppure, con xargs GNU:

xargs -rd '\n' --arg-file=list.txt rm -i --

1
Quindi se avessi nella lista un file chiamato y, il file precedente sarebbe stato cancellato?
Francesco Turco,

5
Non solo y, ma qualsiasi nome che inizia con y. Apparentemente, rmguarda solo il primo carattere di qualunque risposta riceva: 'y' è sì, tutto il resto è no.
Chepner,

1

Per qualcosa di un po 'più elaborato rispetto alla risposta sì o no a ciascun file, è possibile utilizzare iselectper la selezione interattiva basata su ncurses. per esempio

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

o per consentire la selezione di file nella directory corrente:

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

Verrà visualizzato un elenco basato su ncurses a schermo intero (terminale completo), in cui i file possono essere selezionati e deselezionati a piacimento premendo SPACE. premere INVIO per accettare le selezioni (le voci selezionate verranno stampate su stdout) o qper uscire (nulla verrà stampato su stdout). premere hper aiuto.

Nota: l' echo rmho scritto così per i test. cambiarlo solo rmquando sei sicuro di aver capito cosa sta facendo.

Si noti inoltre che xargsviene utilizzato qui con \ncome separatore di input. Questo non funzionerà se uno dei nomi dei file contiene caratteri di avanzamento riga. In ogni caso, iselectneanche funzionerà correttamente - si aspetta un elemento per riga - sfortunatamente, iselectnon ha un'opzione per input o output con terminazione null.

iselectè confezionato per debian, probabilmente ubuntu e altre distribuzioni. la home page è su http://www.ossp.org/pkg/tool/iselect/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.