Encuentra todos los archivos PDF con al menos tres caracteres en su nombre

9

Me gustaría encontrar los archivos PDF cuyo nombre (excluyendo la extensión) es mayor que tres.

$ find ~ -iregex ".{3,}/.pdf"

no devuelve nada, pero

$ find ~ -iregex ".+/.pdf"

trabajos.

¿Cómo puedo habilitar la {3,}variante?

Cálculo
fuente
Que longitud Longitud del nombre de archivo? Longitud de la página?
Ignacio Vázquez-Abrams

Respuestas:

18

Suponiendo que está utilizando GNU find(que probablemente es, ya que -iregexes una extensión de GNU a POSIXfind ), -regexy por -iregexdefecto a las expresiones regulares de Emacs, que no reconocen {3,}. Debe especificar un tipo diferente de expresiones regulares utilizando la -regextypeopción; Además, debe ajustar su expresión regular al hecho de que la expresión coincide con la ruta completa:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}.pdf'

También debe escapar de .modo que coincida con "." en lugar de cualquier personaje:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}\.pdf'

La expresión regular se puede simplificar ya que solo nos interesan tres caracteres que no son "/":

find ~ -regextype posix-extended -iregex '.*[^/]{3}\.pdf'

Para completar, con FreeBSD o NetBSD find(otra implementación que admite -iregex, no la tuya, ya .+que no funcionaría allí sin -E), escribirías:

find ~ -iregex '.*[^/]\{3\}\.pdf'

o:

find -E ~ -iregex '.*[^/]{3}\.pdf'

Sin -E, esa es una expresión regular básica (como en grep) y con -E una expresión regular extendida (como en grep -E).

Con ast-open's find:

find ~ -iregex '.*[^/]{3}\.pdf'

(eso es expresiones regulares extendidas fuera de la caja).

Stephen Kitt
fuente
20

Aquí es más fácil con los comodines estándar:

find ~ -name '*???.[pP][dD][fF]'

O con algunas findimplementaciones (las que -regextambién admiten -iname):

find ~ -iname '*???.pdf'

Para números arbitrarios de caracteres en lugar de 3, es donde puede preferir volver a -iregexdonde esté disponible (consulte la respuesta de @Stephen Kitt ) o puede usar zsho ksh93globs:

  • zsh:

    set -o extendedglob # best in ~/.zshrc
    printf '%s\n' ~/**/?(#c3,).(#i)pdf(D)
    

    ( (D)para considerar archivos ocultos y archivos en directorios ocultos como con find)

    • (#cx,y)es el zshcomodín equivalente de regexp{x,y}
    • (#i) para mayúsculas y minúsculas
    • ?comodín estándar para cualquier carácter individual (como regexp .)
    • **/: cualquier nivel de subdirectorios (incluido 0)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y): operador comodín ksh extendido similar a regexp (x|y).
    • FIGNORE: variable especial que controla qué archivos son ignorados por los globos. Cuando se establece, no se hace caso omiso de los archivos ocultos, pero aún queremos ignorar las entradas del directorio .y ..donde están presentes.
    • {x,y}(z)es ksh93el equivalente de regexp z{x,y}.
    • ~(i:...): coincidencia entre mayúsculas y minúsculas.

Los globs tienen algunas ventajas adicionales findaquí, ya que obtienes una lista ordenada (puedes deshabilitar esa clasificación zshcon el oNcalificador glob o usar diferentes criterios de clasificación) y también funciona cuando los nombres de archivo contienen una secuencia de bytes que no forman caracteres válidos (para Por ejemplo, en un entorno local que utiliza el juego de caracteres UTF-8, el findenfoque no informaría de $'St\xE9phane Chazelas - CV.pdfque, dado que \xE9no es un personaje, no coincide con regexp .o comodín ?o *con GNU find).

Stéphane Chazelas
fuente
¿Funcionaría esto para Bash? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea
7

¿Cómo sé que son archivos PDF?

No lo haces a menos que lo pidas. Claro, estoy siendo pedante, pero no preguntaste sobre los archivos con .pdfsus nombres . El hecho de que un archivo tenga los caracteres .pdfen el nombre de archivo no lo convierte en un archivo PDF .

De hecho, seamos pedantes al respecto: si los últimos cuatro caracteres del nombre de un archivo lo son .pdf, siempre tendrá más de tres caracteres en su nombre .

Entonces, haciendo esto de manera incorrecta , podrías decir:

$ find . -type f -name "*???.pdf"
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Setup_MagicISO.exe.pdf

¿Ves ese segundo? En realidad es un ejecutable. (Lo sé, cambié el nombre). Y también me falta un PDF que podría haber jurado que estaba en el directorio de Documentos ...

$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf

Entonces, usando -inamepodríamos encontrarlo, pero aún así aparece este archivo que no es PDF.

Lo que realmente queremos hacer en este caso es examinar el número mágico del archivo con el filecomando. Una opción genera el tipo MIME , que es más fácil de analizar. La findconsulta se convierte en una simple -name "???*".

$ find . -type f -name "???*" -print0|xargs -0 file --mime
./.bash_history:                                              text/plain; charset=us-ascii
./.bash_logout:                                               text/plain; charset=us-ascii
./.bashrc:                                                    text/plain; charset=us-ascii
./.profile:                                                   text/plain; charset=us-ascii
./Documents/McLaren 720s Coupe:Order Summary.pdf:             application/pdf; charset=binary
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF: application/pdf; charset=binary
./Documents/Setup_MagicISO.exe.pdf:                           application/x-dosexec; charset=binary
./Downloads/Setup_MagicISO.exe:                               application/x-dosexec; charset=binary
./Downloads/WindowsUpdate.diagcab:                            application/vnd.ms-cab-compressed; charset=binary

Usemos el delimitador de dos puntos y busquemos el tipo MIME application/pdf, luego ponmos a cero esa porción e imprimimos el resultado. Tome nota, uno de mis archivos tiene dos puntos en el nombre; así que no puedo pedirle a awk que lo haga ($2==":"){print $1}.

$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF

Ahora terminemos por incluir archivos PDF con el nombre ay abc:

$ mkdir Documents/other
$ cp -a Documents/McLaren\ 720s\ Coupe\:Order\ Summary.pdf Documents/other/a
$ cp -a Documents/Pioneer\ Premier\ DEH-P490IB\ CD\ Install\ Manual.PDF  Documents/other/abc
$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF
./Documents/other/abc

Eso es todo. Sé que probablemente me criticarán por ser terriblemente pedante, pero en mi trabajo con miles de volúmenes NFS para cazar y todo tipo de archivos mal nombrados, desearía que más personas fueran pedantes.

Editado para agregar: en el mundo real, es posible que desee utilizar updatedbpara crear un índice de archivo de búsqueda, en locatelugar de findleer ese índice y en parallellugar de xargsenhebrarlo. Sin embargo, eso está algo fuera del alcance de esta pregunta. También escribí eso con una cara seria. ¿Por qué me importa tanto? Podría estar buscando películas y archivos de audio; o ciertos tipos de fotografías; o ejecutables binarios en un directorio de datos del proyecto.

Rico
fuente
1
Si el autor de la pregunta tiene la misma situación que usted, donde hay archivos PDF cuyos nombres no terminan .pdf, su pedantería será muy apreciada. Pero es una situación relativamente inusual (a pesar de su trabajo) y no tenemos ninguna razón para creer que el autor de la pregunta realmente tenga que lidiar con eso, por lo que creo que el punto que está haciendo, aunque válido, es un poco distractor. y creo que la manera contundente en la que lo has expresado empuja la respuesta al ámbito de "(probablemente) no útil". (Solo mi opinión, por supuesto.)
David Z
Como estamos siendo pedantes, ¿cómo manejaría archivos PDF como los políglotas PoC || GTFO ?
Stephen Kitt
@StephenKitt: no estoy seguro de lo que estás preguntando, pero estoy intrigado. A mí me parecen archivos PDF normales con nombres no particularmente originales. ¿Fallarían estos mi solución sugerida?
Rico
@DavidZ No estoy seguro de qué decir a eso. Quiero decir, ¿no es un poco pedante señalar que soy pedante cuando ya lo dije? He aquí por qué no es "no útil": una buena solución para encontrar archivos PDF debería ser una solución adaptable para encontrar scripts, ejecutables binarios, bibliotecas, archivos multimedia, etc. Ni siquiera puedo comenzar a ver cómo adaptaría uno de los otras respuestas para "ejecutables comprimidos de Mach", pero estoy dispuesto a aprender.
Rico
1
@Rich muchos de los PDF también son archivos ZIP, algunos también son imágenes, o incluso máquinas virtuales de arranque ... (Consulte los enlaces de "spoilers" en los primeros números para obtener sugerencias; el resto están documentados en los propios PDF)
Stephen Kitt