Come eliminare i file elencati in un file di testo


23

Ho un file di testo che ha un elenco di percorsi per vari file. Esiste un comando che posso usare per scorrere tra le righe ed eliminare il file nel percorso indicato?

Risposte:


33

Utilizzare xargs:

xargs rm < file  # or
xargs -a file rm

Ma ciò non funzionerà se i nomi / percorsi dei file contengono caratteri che devono essere salvati.

Se i tuoi nomi di file non hanno nuove righe, puoi fare:

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

In alternativa, puoi creare il seguente script:

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

Salvalo come /usr/local/bin/delete-from, concedi l'autorizzazione all'esecuzione:

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

Quindi eseguilo con:

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

2
Risposta davvero pulita, ma catnon obbligatoria, puoi usare il stdinreindirizzamento:< file xargs rm
kos

Si divide i nomi delle cartelle e poi li cerca. Ad esempio, MY FOLDER viene interpretato come "MY" e "FOLDER"?
daka,

@sudoman Risposta aggiornata.
Eric Carvalho,

Se i file non hanno spazi, potresti semplicemente "rm - $ (file cat)" in bash o "rm - cat file" in (ba) sh o csh.
shooper

@shooper catè inutile, come appena detto, approfittane stdin! Guarda la sua risposta aggiornata
kos

20

Ecco un modo per gestire i nomi dei file con spazi bianchi, barre rovesciate e altri strani caratteri:

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

Questo leggerà ogni riga di list.txt, la salverà come $filee verrà eseguita rmsu di essa. Le -rassicura che backslash vengono letti letteralmente (in modo che \tcorrisponde a un \e un te non un TAB). Le --assicura che si occupa anche di nomi di file che iniziano con -.

Puoi farlo anche in Perl:

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

Questo leggerà ogni nome di file %knell'hash e quindi lo userà unlinkper eliminarli.


10

Attraverso il pitone.

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

Salvare lo script sopra in un file chiamato like script.pye quindi eseguire lo script lanciando il comando seguente sul terminale.

python3 script.py file

file è un file di input in cui sono memorizzati il ​​percorso dei file che si desidera effettivamente rimuovere.


6
Ah, almeno hai il coraggio di pubblicare una risposta in pitone :)
Jacob Vlijm,

3

Stupido, ma eccone uno:

 tar -cvf /dev/null --remove-files -T filename

2

Un altro modo per farlo:

Puoi "preparare" il file rendendolo uno script di shell:

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

Se i tuoi nomi di file possono avere una sola virgoletta ( '), puoi usare questa versione leggermente espansa per sfuggire loro prima:

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

E puoi eseguirlo eseguendo il piping a sh:

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

1

A quanto ho capito, hai un file di testo con i file con i percorsi completi. Vi sono due possibilità:

  1. Il tuo elenco ha i nomi di file separati da nuove righe, ovvero ogni riga ha il percorso completo di un file. in questo caso: ecco una semplice via d'uscita:

    for i in $(cat listOfFiles.txt); do
        rm -f $i
    done
    
  2. Se il tuo elenco ha una o più righe di nomi di file separate da spazi o tabulazioni, ecco il tutorial:

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

    questo convertirà tutti gli spazi bianchi in newline

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

Sì, ci sono molti modi per farlo, ma questo è un approccio molto semplice.

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.