Risposte:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdf
nome fileAd esempio, se esiste una directory chiamata temp
nella 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 .pdf
alla fine. -type f
seleziona solo i file, non le directory. -delete
significa eliminarlo.
!
deve venire prima -name
. -name
includerà semplicemente solo .pdf
, mentre -iname
includerà sia .pdf
e.PDF
Per 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 .pdf
alla fine. -delete
significa eliminarlo. sono chiaro ora?
-maxdepth 1
parametro per cominciare. Quindi suggerire di rimuovere il parametro nel caso si desideri eliminare in modo ricorsivo.
Con bash
il globbing esteso della shell, è possibile rimuovere qualsiasi file con estensioni diverse .pdf
dall'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 rm
comando, con conseguente errore come
rm: cannot remove `*.!(pdf)': No such file or directory
È possibile modificare questo comportamento predefinito utilizzando l' nullglob
opzione 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 mv
comando (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 rm
utilizzare xargs
. Per esempio:
ls
mi mostra tuttols | grep pdf
mi mostra i file che voglio conservare. Hmm.ls | grep -v pdf
mostra 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 rm
invia esattamente tale elenco rm
per la cancellazioneCome ho detto, mi piace principalmente questo per la sicurezza che fornisce: nessun incidente rm *
per me. Altri due vantaggi:
ls
o find
per ottenere l'elenco iniziale, come preferisci. Puoi usare qualsiasi altra cosa ti piaccia nel processo di restringimento di tale elenco - un altro grep
, alcuni awk
o qualunque cosa. Se fosse necessario eliminare solo i file i cui nomi contengono un colore, è possibile crearlo nello stesso modo.find
per trovare e rm
rimuovere, piuttosto che dover ricordare che find
accetta una -delete
bandiera. E se lo fai, ancora una volta, puoi comporre soluzioni alternative; forse invece di rm
, potresti creare un trash
comando che sposta il file nel cestino (consentendo "undeletion") e reindirizza a quello invece di rm
. Non è necessario disporre del find
supporto 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.
pdf
ovunque 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 ls
sostituzione 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 -20
almeno vedere se sembra approssimativamente corretto, mentre se solo rm my_pattern
non 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 find
o 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 file
comando.
$ 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 for
comando è dare i file nella directory corrente sotto forma di variabile $var
. if-then
Il comando genera i nomi dei file pdf prendendo lo stato di uscita 0
dal file -i "$var" | grep -q 'application/pdf\;'
comando, darà lo stato di uscita 0
solo 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}')
-i
con grep
per la corrispondenza case-insensitive.
rm -i -- !(*@(a|x).pdf)
Leggi come, rimuovi tutti i file che non lo sono a.pdf
o 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ù a
o x
modelli prima del .pdf
suffisso. 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 bash
il 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"-name
significa che si desidera escludere con un parametro name e quindi-delete
l'azione da intraprendere al momento della ricerca? Quindi cerca tutto tranne "* .pdf" e li elimina? O ho frainteso?