Respuestas:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdfen nombre de archivoPor ejemplo, si hay un directorio llamado tempen su carpeta de inicio:
cd ~/temp
luego borre los archivos:
find . -type f ! -iname "*.pdf" -delete
Esto eliminará todos los archivos excepto xyz.pdf.
Puede combinar estos dos comandos para:
find ~/temp -type f ! -iname "*.pdf" -delete
.es el directorio actual !significa tomar todos los archivos excepto los que están .pdfal final. -type fselecciona solo archivos, no directorios. -deletesignifica eliminarlo.
!debe venir antes -name. simplemente -nameincluirá solo .pdf, mientras -inameque incluirá ambos .pdfy.PDFPara eliminar solo en el directorio actual y no en los subdirectorios, agregue -maxdepth 1:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.significa directorio actual. !significa tomar todos los archivos excepto el que está .pdfal final. -deletesignifica eliminarlo. ¿Estoy claro ahora?
-maxdepth 1parámetro para empezar. Luego sugiera eliminar el parámetro en caso de que se quiera eliminar de forma recursiva.
Con bashel globing de shell extendido, puede eliminar cualquier archivo con extensiones que no sean .pdfusar
rm -- *.!(pdf)
Como señaló @pts, los --caracteres indican el final de cualquier opción de comando, haga que el comando sea seguro en el raro caso de archivos cuyos nombres comiencen con un -carácter.
Si desea eliminar archivos sin ninguna extensión, así como aquellos con extensiones que no sean .pdf, entonces, como lo señaló @DennisWilliamson, podría usar
rm -- !(*.pdf)
El globbing extendido debe estar habilitado de forma predeterminada, pero si no, puede hacerlo utilizando
shopt -s extglob
Especialmente si tiene la intención de usar esto dentro de un script, es importante tener en cuenta que si la expresión no coincide con nada (es decir, si no hay archivos que no sean pdf en el directorio), de forma predeterminada, el globo se pasará sin expandir al rmcomando, lo que resulta en un error como
rm: cannot remove `*.!(pdf)': No such file or directory
Puede modificar este comportamiento predeterminado utilizando la nullglobopción de shell, sin embargo, eso tiene su propio problema. Para una discusión más completa ver NullGlob - Greg's Wiki
rm *~*.pdf
!(*.py). Además, presumiblemente, si el OP solo quiere archivos ".pdf" restantes, entonces los archivos sin extensiones también deberían eliminarse y no ignorarse.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
O a través de un mvcomando (pero de esta manera no puede restaurarlo desde la Papelera ya que no registra información .trashinfo, por lo que esto significa que movió sus archivos a un destino donde está de la siguiente manera).
mv !(*.pdf) ~/.local/share/Trash/files
rm.
El enfoque más fácil: cree otro directorio en algún lugar (si solo está eliminando en un directorio, no de forma recursiva, incluso puede ser un subdirectorio); mueve todos los archivos .pdf allí; eliminar todo lo demás; mueve el pdf hacia atrás; Eliminar el directorio intermedio.
Rápido, fácil, puedes ver exactamente lo que estás haciendo. ¡Solo asegúrese de que el directorio intermedio esté en el mismo dispositivo que el directorio que está limpiando para que los movimientos sean renombrados, no copias!
Utilice el GLOBIGNORE de bash:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
De la página de manual de bash:
GLOBIGNORE:
Una lista de patrones separados por dos puntos que definen el conjunto
de nombres de archivo a ignorar por la expansión de nombre de ruta.
Una prueba rápida:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Salida:
y.zip z.mp3
Aquí hay un enfoque que me gusta, porque me permite ser muy cuidadoso: componga una forma de mostrar solo los archivos que quiero eliminar y luego envíelos a rmusar xargs. Por ejemplo:
ls me muestra todols | grep pdfme muestra los archivos que quiero conservar. Hmmls | grep -v pdfmuestra lo contrario: todo excepto lo que quiero conservar. En otras palabras, muestra la lista de cosas que quiero eliminar. Puedo confirmar esto antes de hacer algo peligroso.ls | grep -v pdf | xargs rmenvía exactamente esa lista rmpara su eliminaciónComo dije, me gusta principalmente por la seguridad que proporciona: no es accidental rm *para mí. Otras dos ventajas:
lso findpara obtener la lista inicial, como prefiera. Puede usar cualquier otra cosa que desee en el proceso de reducir esa lista: otra grep, alguna awko lo que sea. Si necesita eliminar solo archivos cuyos nombres contienen un color, puede crearlo de la misma manera.findpara buscar y rmeliminar, en lugar de tener que recordar que findacepta una -deletebandera. Y si hace esto, nuevamente, puede componer soluciones alternativas; tal vez en lugar de rm, podría crear un trashcomando que mueva el archivo a la papelera (permitiendo "eliminar") y canalizarlo a ese en lugar de rm. No necesita tener findsoporte para esa opción, solo tiene que canalizarla.Vea los comentarios de @pabouk para ver cómo modificar esto para manejar algunos casos extremos, como saltos de línea en nombres de archivos, nombres de archivos como my_pdfs.zip, etc.
pdfcualquier parte de su nombre. --- b) Eliminará los archivos PDF si alguna de las letras del sufijo es mayúscula. --- c) No es una buena idea utilizar la salida de ls. No funcionará con nombres de archivo que contengan nuevas líneas. Algunas implementaciones de lsreemplazar caracteres especiales, por ejemplo, tab ?. --- Es mejor uso: find -maxdepth 1 -print0. (no tan corto como ls:) ----- Para resolver a) yb) use grep -vi '\.pdf$'--- solución completa (pero solo GNU):find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20al menos puede ver si se ve más o menos correcto, mientras que si simplemente rm my_patternno tiene la oportunidad de detectar un gran error.
find . -type f ! -name "*.pdf"para imprimir en la consola, o canalizar a menos o un archivo. [y luego canalice a xargs a rm si lo desea, como los comentarios de pabouk (con el -print0 | ... -0 para nombres de archivo extraños)]
Por lo general, resuelvo estos problemas con el intérprete interactivo de Python:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Puede ser más largo que una línea con findo xargs, pero es extremadamente resistente y sé exactamente lo que hace, sin tener que investigarlo primero.
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')]
La mejor respuesta (en comparación con mi respuesta anterior) a esta pregunta será utilizando el poderoso filecomando.
$ file -i abc.pdf
abc: application/pdf; charset=binary
ahora tu 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
el trabajo de forcomando es dar los archivos en el directorio actual en forma de variable $var. if-thenEl comando genera los nombres de los archivos pdf tomando el estado de salida 0del file -i "$var" | grep -q 'application/pdf\;'comando from , dará el estado de salida de 0solo si encuentra archivos pdf.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
¡Advertencia! Mejor inténtalo primero
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-icon greppara la combinación de mayúsculas y minúsculas
rm -i -- !(*@(a|x).pdf)
Leer como, eliminar todos los archivos que no son a.pdfo x.pdf.
Esto funciona mediante la utilización de globos 2 extendidos, el exterior !()para negar el pegote contenida que a su vez requiere que el pegote debe coincidir con uno o más de ao xpatrones antes del .pdfsufijo. Ver 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'
Más o menos POSIX y compatible con cualquier cáscara de estilo Bourne ( ksh, bash, dash). Muy adecuado para scripts portátiles y cuando no se puede utilizar bashel globing de shell extendido.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
O un poco más limpio:
$ 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(".")))'
¡Ten cuidado con lo que estás borrando!
Una forma segura de probarlo antes de intentar eliminar es probar primero ls, ya que algunos comportamientos no detectados podrían eliminar archivos no deseados. Y puede hacerlo directamente fuera del directorio. lses similar a rm, entonces:
ls sub/path/to/files/!(*.pdf)
Esto listará
y.zip
z.mp3
Y ahora puede ver lo que está eliminando y puede eliminarlos de forma segura:
rm sub/path/to/files/!(*.pdf)
Y eso es. Puede usar comodines *para ser más selectivo, como conservar solo los documentos del curso de programación:
rm sub/path/to/files/!(*programming*)
.significa "y"?!significa "excepto"-namesignifica que desea excluir mediante un parámetro de nombre y, ¿cuál-deletees la acción que debe tomar al encontrarlo? Entonces, ¿busca todo excepto "* .pdf" y los elimina? ¿O he entendido mal?