In Linux, come eliminare tutti i file TRANNE il modello * .txt?


74

So come eliminare tutti i txtfile nella directory corrente da rm *.txt. Qualcuno sa come eliminare tutti i file nella directory corrente EXCEPT txtfile?


21
Come sempre, prova le risposte fornite con un comando innocuo come lsprima di tentare effettivamente di chiamare rm.
Chepner,

^ A questo ragazzo non piace vivere pericolosamente .. :)
jDub9

Risposte:


111

Puoi usare find:

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

O le funzionalità di globbing estese di bash:

shopt -s extglob
rm *.!(txt)

O in zsh:

setopt extendedglob
rm *~*.txt(.)
#  ||     ^^^ Only plain files
#  ||^^^^^ files ending in ".txt"
#  | \Except
#   \Everything

Alcuni di questi potrebbero dover essere adattati a seconda che tu abbia le cartelle e cosa vuoi fare con esse.
Kevin,

1
Non dovrebbe *.!(txt)essere !(*.txt)?
Lri,

@LauriRanta dipende da cosa c'è nella cartella, a cui non abbiamo ottenuto una risposta. Va bene come se tutti i file abbiano estensioni e rmsi soffocerebbe se ci fossero cartelle.
Kevin,

Ho un problema con le parentesi. Quando uso lo stile globbing in uno script bash, mi lamento di un errore di sintassi e delle parentesi. Tuttavia, farlo dalla CLI funziona.
CMCDragonkai,

1
@izogfif controlla find . -type f ! -name "*.txt" | xargs -r rmche funzionerebbe in GNU \ xargs. Il comando xargs BSD e UNIX potrebbe non avere -r devi controllare il tuo localeman xargs
Ntwobike

10

ci sono molti modi per farlo. ma il modo più semplice sarebbe (bash):

shopt -s extglob
rm !(*.txt)

10

Se desideri solo eliminare tutti i file tranne '* .txt', puoi utilizzare il seguente comando:

$ find . -type f ! -name "*.txt" -exec rm -rf {} \;

ma se vuoi anche eliminare le directory insieme ai file, puoi usare questo:

$ find . ! -name "*.txt" -exec rm -r {} \;


4

Una soluzione senza find:

mv dir/*.txt otherdir/
rm -r dir
mv otherdir dir

Questo dovrebbe funzionare su tutti i tipi di shell.


3

Puoi usare grep e xargs invertiti

ls | grep -v .txt$| xargs rm

ls | grep -v *.txt | xargs rmfunziona altrettanto bene
phillipsk,

@phillipsk grep -v *.txtfunzionerà solo se c'è esattamente un .txtfile. Se non ce n'è, grepuserà *.txtcome modello; se ce n'è più di uno, cercherà il primo nome file all'interno di tutti gli altri .txtfile, ignorando l'output da ls. (I risultati esatti potrebbero dipendere dalle opzioni glob della shell.)
JigglyNaga,

.txt$corrisponderà alle stringhe che terminano txtindipendentemente dal punto. Perché grepaccetta l'espressione regolare come parametro. Così i file a.txte le aatxte a-txtsaranno tutti abbinati con questa espressione. L'espressione corretta dovrebbe essere ls | grep -v \\.txt$ | xargs --no-run-if-empty rm. Per le persone curiose: se vuoi giocare con l'espressione in modo sicuro usa questa espressione di prova ls | grep \\.txt$ | xargs --no-run-if-empty echo(nota: non c'è -vbandiera e rm=>echo). Nota2: potresti aver notato una doppia barra rovesciata. Uno è per regex, un altro è per bash per sfuggire alla barra.
Dimitry K

1

Fai semplicemente:

rm $(ls -I "*.txt" ) # Elimina il tipo di file tranne * .txt

Allo stesso modo, se è necessario eliminare "tranne uno o più tipi di file", eseguire:

rm $(ls -I "*.txt" -I "*.pdf" ) # Elimina i tipi di file tranne * .txt & * .pdf


Benvenuto in StackExchange! L' -Iopzione potrebbe essere utile, ma vedi perché non analizzare ls . E che cosa | xargsottiene? Senza alcun argomento, funziona solo echosu tutti i suoi input.
JigglyNaga,

Cosa xargsdovrebbe raggiungere?
Dhag,

Grazie, xargs non è stato utile nel caso precedente, ora ho corretto.
Surya,

0

Questo funziona anche per rimuovere tutti i file e le cartelle nascosti (punto) tranne quello indicato ( .mydir):

rm -rf $(ls -aI ".mydir")
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.