Respuestas:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdf
en nombre de archivoPor ejemplo, si hay un directorio llamado temp
en 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 .pdf
al final. -type f
selecciona solo archivos, no directorios. -delete
significa eliminarlo.
!
debe venir antes -name
. simplemente -name
incluirá solo .pdf
, mientras -iname
que incluirá ambos .pdf
y.PDF
Para 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á .pdf
al final. -delete
significa eliminarlo. ¿Estoy claro ahora?
-maxdepth 1
parámetro para empezar. Luego sugiera eliminar el parámetro en caso de que se quiera eliminar de forma recursiva.
Con bash
el globing de shell extendido, puede eliminar cualquier archivo con extensiones que no sean .pdf
usar
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 rm
comando, lo que resulta en un error como
rm: cannot remove `*.!(pdf)': No such file or directory
Puede modificar este comportamiento predeterminado utilizando la nullglob
opció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 mv
comando (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 rm
usar xargs
. Por ejemplo:
ls
me muestra todols | grep pdf
me muestra los archivos que quiero conservar. Hmmls | grep -v pdf
muestra 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 rm
envía exactamente esa lista rm
para su eliminaciónComo dije, me gusta principalmente por la seguridad que proporciona: no es accidental rm *
para mí. Otras dos ventajas:
ls
o find
para obtener la lista inicial, como prefiera. Puede usar cualquier otra cosa que desee en el proceso de reducir esa lista: otra grep
, alguna awk
o lo que sea. Si necesita eliminar solo archivos cuyos nombres contienen un color, puede crearlo de la misma manera.find
para buscar y rm
eliminar, en lugar de tener que recordar que find
acepta una -delete
bandera. Y si hace esto, nuevamente, puede componer soluciones alternativas; tal vez en lugar de rm
, podría crear un trash
comando que mueva el archivo a la papelera (permitiendo "eliminar") y canalizarlo a ese en lugar de rm
. No necesita tener find
soporte 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.
pdf
cualquier 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 ls
reemplazar 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 -20
al menos puede ver si se ve más o menos correcto, mientras que si simplemente rm my_pattern
no 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 find
o 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 file
comando.
$ 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 for
comando es dar los archivos en el directorio actual en forma de variable $var
. if-then
El comando genera los nombres de los archivos pdf tomando el estado de salida 0
del file -i "$var" | grep -q 'application/pdf\;'
comando from , dará el estado de salida de 0
solo 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}')
-i
con grep
para la combinación de mayúsculas y minúsculas
rm -i -- !(*@(a|x).pdf)
Leer como, eliminar todos los archivos que no son a.pdf
o 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 a
o x
patrones antes del .pdf
sufijo. 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 bash
el 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. ls
es 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"-name
significa que desea excluir mediante un parámetro de nombre y, ¿cuál-delete
es la acción que debe tomar al encontrarlo? Entonces, ¿busca todo excepto "* .pdf" y los elimina? ¿O he entendido mal?