Risposte:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdfnome fileAd esempio, se esiste una directory chiamata tempnella cartella principale:
cd ~/temp
quindi eliminare i file:
find . -type f ! -iname "*.pdf" -delete
Ciò eliminerà tutti i file tranne xyz.pdf.
È possibile combinare questi due comandi per:
find ~/temp -type f ! -iname "*.pdf" -delete
.è la directory corrente. !significa prendere tutti i file tranne quelli con .pdfalla fine. -type fseleziona solo i file, non le directory. -deletesignifica eliminarlo.
!deve venire prima -name. -nameincluderà semplicemente solo .pdf, mentre -inameincluderà sia .pdfe.PDFPer eliminare solo nella directory corrente e non nelle sottodirectory aggiungere -maxdepth 1:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.indica la directory corrente. !significa prendere tutti i file tranne quello con .pdfalla fine. -deletesignifica eliminarlo. sono chiaro ora?
-maxdepth 1parametro per cominciare. Quindi suggerire di rimuovere il parametro nel caso si desideri eliminare in modo ricorsivo.
Con bashil globbing esteso della shell, è possibile rimuovere qualsiasi file con estensioni diverse .pdfdall'uso
rm -- *.!(pdf)
Come notato da @pts, i --caratteri indicano la fine di qualsiasi opzione di comando, rendono il comando sicuro nel raro caso di file il cui nome inizia con un -carattere.
Se si desidera eliminare i file senza alcuna estensione e quelli con estensioni diverse da .pdf, quindi come sottolineato da @DennisWilliamson è possibile utilizzare
rm -- !(*.pdf)
Il globbing esteso dovrebbe essere abilitato per impostazione predefinita, ma in caso contrario è possibile farlo utilizzando
shopt -s extglob
Soprattutto se si intende utilizzarlo all'interno di uno script, è importante notare che se l'espressione non corrisponde a nulla (ovvero se non ci sono file non pdf nella directory), per impostazione predefinita il glob verrà passato non espanso al rmcomando, con conseguente errore come
rm: cannot remove `*.!(pdf)': No such file or directory
È possibile modificare questo comportamento predefinito utilizzando l' nullglobopzione shell, tuttavia ha un suo problema. Per una discussione più approfondita vedi NullGlob - Greg's Wiki
rm *~*.pdf
!(*.py). Inoltre, presumibilmente, se l'OP desidera che rimangano solo i file ".pdf", anche i file senza estensioni devono essere eliminati e non ignorati.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
O tramite mvcomando (ma in questo modo non è possibile ripristinarlo dal Cestino poiché non registra le informazioni .trashinfo, quindi questo significa che hai spostato i tuoi file in una destinazione dove è come segue).
mv !(*.pdf) ~/.local/share/Trash/files
rm.
L'approccio più semplice: creare un'altra directory da qualche parte (se si sta eliminando solo una directory, non ricorsivamente, può anche essere una sottodirectory); sposta lì tutti i .pdf; elimina tutto il resto; sposta indietro il pdf; elimina la directory intermedia.
Veloce, facile, puoi vedere esattamente cosa stai facendo. Assicurati solo che la directory intermedia sia sullo stesso dispositivo della directory che stai ripulendo in modo che le mosse siano rinominazioni, non copie!
Usa GLOBIGNORE di bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Dalla pagina man di bash:
GLOBIGNORE:
Un elenco separato da due punti di motivi che definiscono il set
di nomi di file che devono essere ignorati dall'espansione del percorso.
Un rapido test:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Produzione:
y.zip z.mp3
Ecco un approccio che mi piace, perché mi consente di stare molto attento: componi un modo per mostrare solo i file che voglio eliminare, quindi inviali a rmutilizzare xargs. Per esempio:
ls mi mostra tuttols | grep pdfmi mostra i file che voglio conservare. Hmm.ls | grep -v pdfmostra il contrario: tutti tranne quello che voglio mantenere. In altre parole, mostra l'elenco delle cose che voglio eliminare. Posso confermarlo prima di fare qualcosa di pericoloso.ls | grep -v pdf | xargs rminvia esattamente tale elenco rmper la cancellazioneCome ho detto, mi piace principalmente questo per la sicurezza che fornisce: nessun incidente rm *per me. Altri due vantaggi:
lso findper ottenere l'elenco iniziale, come preferisci. Puoi usare qualsiasi altra cosa ti piaccia nel processo di restringimento di tale elenco - un altro grep, alcuni awko qualunque cosa. Se fosse necessario eliminare solo i file i cui nomi contengono un colore, è possibile crearlo nello stesso modo.findper trovare e rmrimuovere, piuttosto che dover ricordare che findaccetta una -deletebandiera. E se lo fai, ancora una volta, puoi comporre soluzioni alternative; forse invece di rm, potresti creare un trashcomando che sposta il file nel cestino (consentendo "undeletion") e reindirizza a quello invece di rm. Non è necessario disporre del findsupporto per questa opzione, è sufficiente eseguire il pipe.Vedi i commenti di @pabouk su come modificarlo per gestire alcuni casi limite, come interruzioni di riga nei nomi di file, nomi di file come my_pdfs.zip, ecc.
pdfovunque nel suo nome. --- b) Eliminerà i file PDF se una delle lettere nel suffisso è in maiuscolo. --- c) Non è una buona idea usare l'output di ls. Non funzionerà con nomi di file contenenti newline. Alcune implementazioni di lssostituzione di caratteri speciali, ad esempio tab by ?. --- E 'meglio usare: find -maxdepth 1 -print0. (non così breve come ls:) ----- Per risolvere a) eb) utilizzare grep -vi '\.pdf$'--- soluzione completa (ma solo GNU):find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20almeno vedere se sembra approssimativamente corretto, mentre se solo rm my_patternnon hai la possibilità di individuare un grosso errore.
find . -type f ! -name "*.pdf"per stampare su console, o pipe su less o un file. [e poi reindirizza a xargs per rm se lo desideri, come i commenti di pabouk (con -print0 | ... -0 per nomi di file strani)]
Solitamente risolvo questi problemi dall'interprete interattivo di Python:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Potrebbe essere più lungo di un one-liner con findo xargs, ma è estremamente resistente e so esattamente cosa fa, senza doverlo prima cercare.
for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
una risposta migliore (rispetto alla mia precedente risposta) a questa domanda sarà usando il potente filecomando.
$ file -i abc.pdf
abc: application/pdf; charset=binary
ora il tuo problema:
cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done
il lavoro del forcomando è dare i file nella directory corrente sotto forma di variabile $var. if-thenIl comando genera i nomi dei file pdf prendendo lo stato di uscita 0dal file -i "$var" | grep -q 'application/pdf\;'comando, darà lo stato di uscita 0solo se trova i file pdf.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Avvertimento! Meglio provare prima
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-icon grepper la corrispondenza case-insensitive.
rm -i -- !(*@(a|x).pdf)
Leggi come, rimuovi tutti i file che non lo sono a.pdfo x.pdf.
Funziona facendo uso di 2 globi estesi, l'esterno !()per negare il glob contenuto che a sua volta richiede che il glob debba corrispondere a uno o più ao xmodelli prima del .pdfsuffisso. Vedi glob # extglob .
$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3
$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3
$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3
$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3
$ echo -- !(@(a|x).pdf) # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3
$ echo -- !(*@(a|x).pdf) # but this doesn't
-- y.zip z.mp3
$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3
$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'
Praticamente POSIX e compatibile con qualsiasi shell stile Bourne ( ksh, bash, dash). Adatto per script portatili e quando non è possibile utilizzare bashil globbing esteso della shell.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
O leggermente più pulito:
$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'
python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'
Fai attenzione a ciò che stai eliminando!
Un modo sicuro per testarlo prima di provare a eliminare è quello di testare prima ls, poiché alcuni comportamenti non rilevati potrebbero eliminare file indesiderati. E puoi farlo direttamente fuori dalla directory. lsè simile a rm, quindi:
ls sub/path/to/files/!(*.pdf)
Questo elencherà
y.zip
z.mp3
E ora puoi vedere cosa stai eliminando e puoi eliminarli in sicurezza:
rm sub/path/to/files/!(*.pdf)
E questo è tutto. Puoi usare i caratteri jolly *per essere più selettivo come conservare solo i documenti del corso di programmazione:
rm sub/path/to/files/!(*programming*)
.significa "e"?!significa "tranne"-namesignifica che si desidera escludere con un parametro name e quindi-deletel'azione da intraprendere al momento della ricerca? Quindi cerca tutto tranne "* .pdf" e li elimina? O ho frainteso?