Eliminazione di file con spazi nei loro nomi


10

Sto cercando di eliminare tutti i file con uno spazio nei loro nomi. Sto usando il seguente comando. Ma mi sta dando un errore

Comando: ls | egrep '. ' | xargs rm

Qui se sto usando solo il ls | egrep '. 'comando mi sta dando tutto il nome del file con spazi nei nomi dei file. Ma quando sto cercando di passare l'output a rm, tutti gli spazi (iniziali o finali) vengono eliminati. Quindi il mio comando non viene eseguito correttamente.

Qualche suggerimento su come eliminare il file con almeno uno spazio nel loro nome?

Risposte:


29

È possibile utilizzare il globbing standard sul rmcomando:

rm -- *\ *

Ciò eliminerà qualsiasi file il cui nome contiene uno spazio; lo spazio è evaso in modo che la shell non lo interpreti come un separatore. L'aggiunta --eviterà problemi con i nomi dei file che iniziano con trattini (non saranno interpretati come argomenti da rm).

Se vuoi confermare ogni file prima che venga eliminato, aggiungi l' -iopzione:

rm -i -- *\ *

4
Sicuramente vorresti passare questo attraverso un echoprimo, per proteggerti dai refusi. Aggiungi echoin primo piano e stamperà tutti i file che rimuoverà.
Riking

1
Anuj, il motivo per cui questo ha il maggior numero di voti è che, sebbene findsia potente, a volte non è necessario uccidere il pollo con una mitragliatrice. Gli amministratori UNIX generalmente non ricorrono a find(ad esempio) "rimuovono tutti i file che iniziano con la lettera A" ... uno semplicemente rm A*. Allo stesso modo per rimuovere file contenenti spazi, rm può fare il lavoro. In altre parole, non lasciarti ingannare perché lo spazio è invisibile ed è trattato appositamente dalla shell. Basta scappare, come ha fatto Stephen Kitt, e puoi pensarlo come qualsiasi altro personaggio.
Mike S,

14

Eviterei di analizzare l' lsoutput

Perchè no :

find . -type f -name '* *' -delete

Nessun problema con rm:-).

Anche se questo è ricorsivo e cancellerà tutti i file con spazio nella directory corrente e nelle directory nidificate, come menzionato nei commenti.


4
(1) puoi usare al -name '* *'posto del regex; e (2) è possibile utilizzare -print0 | xargs -0 rm -iper rispondere alle preoccupazioni di @K StephenKitt.
Kevin,

1
Non c'è bisogno di xargs. Basta usare-exec rm -i '{}' +
R .. GitHub FERMA AIUTANDO ICE

1
@Mhmd Ha più insidie ​​di una console di gioco a 8 bit. mywiki.wooledge.org/ParsingLs
Daenyth l'

1
Se si desidera evitare le sottodirectory, utilizzare find . -maxdepth 1 -name '* *' -delete.
Mikkel,

1
@BenjaminW. riparato?
solsTiCe

6

Guarda questo Supponiamo che il nome "file strano"

Soluzione 1

rm strange\ file

soluzione due

rm "strange file"

soluzione tre

ls -i "strange file"

allora vedi l'inode

find . -inum "numberoofinode" -exec rm {} \;

In caso di nomi di file molto strani come

!-filename or --filename

uso

rm ./'!-filename'

4

A partire dal man xargs

xargs legge gli elementi dall'input standard, delimitato da spazi (che possono essere protetti con virgolette doppie o singole o una barra rovesciata) o newline, ed esegue il comando (il default è / bin / echo) una o più volte con qualsiasi argomento iniziale seguito dagli articoli letti dallo standard input. Le righe vuote sull'input standard vengono ignorate.

Possiamo (principalmente) correggere il tuo comando iniziale cambiando il delimitatore xargs in una nuova riga:

ls | egrep '. ' | xargs -d '\n' rm (non farlo ... continua a leggere)

Ma cosa succede se il nome file contiene una nuova riga?

touch "filename with blanks and newline"

Poiché i nomi di file Unix possono contenere spazi vuoti e righe , questo comportamento predefinito è spesso problematico; i nomi di file contenenti spazi vuoti e / o newline vengono elaborati in modo errato da xargs. In queste situazioni è meglio usare l'opzione -0 , che impedisce tali problemi.

ls è davvero uno strumento per il consumo diretto da parte di un essere umano , invece dobbiamo usare il findcomando che può separare i nomi dei file con un carattere null ( -print0). Dobbiamo anche dire a grep di usare caratteri null per separare input ( -z) e output ( -Z). Infine, diciamo a xargs di usare anche caratteri null ( -0)

find . -type f -print0 | egrep '. ' -z -Z | xargs -0 rm



-1

Per farlo in questo modo, avrai bisogno -Zdell'opzione grep e -0dell'opzione xargs. Ma non lo farei in questo modo ( lsnon è lo strumento giusto per il lavoro, ci sono molti problemi nel far leggere il suo output al computer).

Vedi altre risposte per un modo migliore.


Anche

ls | …è equivalente a ls -d *eecho * | …

Tutti questi hanno problemi. Pertanto non utilizzare in lsquesto modo, utilizzare una soluzione da un'altra risposta.


Anche ls *quando le pipe emettono i nomi dei file della nuova riga delimitati. echo(almeno alcune echoimplementazioni) espande le sequenze di barre rovesciate. grep -Zè per la scrittura di nomi di file delimitati da NUL durante l'utilizzo -l, non sarà di aiuto qui. Se intendevi -z, ciò non sarebbe di aiuto, poiché la maggior parte delle lsimplementazioni non ha un'opzione per l'output di nomi di file delimitati da NUL. Si potrebbe fare qualcosa come printf '%s\0' * | grep -z ' ' | xargs -r0 rm -fse.
Stéphane Chazelas,

1
@Kusalananda Penso di averlo corretto.
ctrl-alt-delor,
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.