Trouver tous les PDF contenant au moins trois caractères dans leur nom


9

Je souhaite retrouver les fichiers PDF dont le nom (hors extension) est supérieur à trois.

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

ne renvoie rien, mais

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

travaux.

Comment puis-je activer la {3,}variante?


Quelle longueur? Longueur du nom de fichier? Longueur de page?
Ignacio Vazquez-Abrams

Réponses:


18

En supposant que vous utilisez GNU find(ce que vous êtes probablement, car -iregexc'est une extension GNU pour POSIXfind ), -regexet -iregexpar défaut pour les expressions régulières Emacs, qui ne reconnaissent pas {3,}. Vous devez spécifier un type différent d'expressions régulières à l'aide de l' -regextypeoption; en outre, vous devez ajuster votre expression régulière au fait que l'expression correspond au chemin complet:

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

Vous devez également échapper au .afin qu'il corresponde à "." plutôt que n'importe quel caractère:

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

L'expression régulière peut être simplifiée car nous ne nous soucions que de trois caractères non «/»:

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

Pour être complet, avec FreeBSD ou NetBSD find(une autre implémentation qui prend en charge -iregex, pas la vôtre, car .+cela ne fonctionnerait pas sans -E), vous écririez:

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

ou:

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

Sans -E, c'est une expression régulière de base (comme dans grep) et avec -E une expression régulière étendue (comme dans grep -E).

Avec ast-open find:

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

(c'est regexps étendu hors de la boîte).


20

Ici, c'est plus facile avec les caractères génériques standard:

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

Ou avec certaines findimplémentations (celles qui prennent en -regexcharge prennent également en charge -iname):

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

Pour des nombres arbitraires de caractères au lieu de 3, c'est là que vous préférerez peut-être revenir à l' -iregexendroit où ils sont disponibles (voir la réponse de @Stephen Kitt ) ou vous pouvez utiliser zshou ksh93globs:

  • zsh:

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

    (le (D)pour considérer les fichiers cachés et les fichiers dans des répertoires cachés comme avec find)

    • (#cx,y)est l' zshéquivalent générique de l'expression rationnelle{x,y}
    • (#i) insensible à la casse
    • ?caractère générique standard pour tout caractère unique (comme l'expression régulière .)
    • **/: tout niveau de sous-répertoires (dont 0)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y): opérateur générique ksh étendu similaire à l'expression rationnelle (x|y).
    • FIGNORE: variable spéciale qui contrôle quels fichiers sont ignorés par les globes. Lorsqu'il est défini, l'ignorance habituelle des fichiers cachés n'est pas effectuée, mais nous voulons toujours ignorer les entrées du répertoire .et ..là où elles sont présentes.
    • {x,y}(z)est ksh93l'équivalent de regexp z{x,y}.
    • ~(i:...): correspondance insensible à la casse.

Les globes ont quelques avantages supplémentaires findici dans la mesure où vous obtenez une liste triée (vous pouvez désactiver ce tri zshavec le oNqualificatif glob ou utiliser différents critères de tri) et également fonctionner lorsque les noms de fichiers contiennent une séquence d'octets qui ne forment pas de caractères valides (pour Par exemple, dans un environnement local utilisant le jeu de caractères UTF-8, l' findapproche échouerait à signaler un $'St\xE9phane Chazelas - CV.pdfcar ce \xE9n'est pas un caractère qui ne correspond pas à l'expression rationnelle .ou au caractère générique ?ou *à GNU find).


Est-ce que cela fonctionnerait pour Bash? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea

7

Comment savoir si ce sont des PDF?

Vous ne le faites pas sauf si vous le demandez. Bien sûr, je suis pédant, mais vous n'avez pas posé de questions sur les fichiers avec .pdfleur nom . Le fait qu'un fichier ait des caractères .pdfdans le nom de fichier n'en fait pas un fichier PDF .

En fait, soyons pédant à ce sujet: si les quatre derniers caractères du nom d'un fichier le sont .pdf, il aura toujours plus de trois caractères dans son nom .

Donc, en faisant cela dans le mauvais sens , vous pourriez dire:

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

Vous voyez ce deuxième? C'est en fait un exécutable. (Je sais, j'ai changé le nom.) Et il me manque aussi un PDF que je pourrais jurer être dans le répertoire Documents ...

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

Donc, en utilisant, -inamenous pourrions trouver celui-là, mais cela continue de générer ce fichier non PDF.

Ce que nous voulons vraiment faire dans ce cas, c'est examiner le nombre magique du fichier à l' aide de la filecommande. Une option génère le type MIME , qui est plus simple à analyser. La findrequête devient alors 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

Utilisons le délimiteur deux-points, recherchons le type MIME application/pdf, puis remettons à zéro cette partie et imprimons le résultat. Prenez note, un de mes fichiers a un deux-points dans le nom; donc je ne peux pas demander à awk ($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

Terminons maintenant en essayant d'inclure les fichiers PDF nommés aet 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

C'est tout. Je sais que je serai probablement fatigué d'être horriblement pédant, mais dans mon travail avec des milliers de volumes NFS à chasser et toutes sortes de fichiers mal nommés, je souhaite que plus de gens soient pédants.

Modifié pour ajouter: dans le monde réel, je pourrais vouloir utiliser updatedbpour construire un index de fichier consultable, locateau lieu de findlire cet index, et parallelau lieu de l' xargsenfiler. C'est quelque peu en dehors de la portée de cette question. J'ai aussi écrit ça avec un visage impassible. Pourquoi je m'en soucie autant? Je recherche peut-être des films et des fichiers audio; ou certains types de photographies; ou exécutables binaires dans un répertoire de données de projet.


1
Si le demandeur a la même situation que vous, où il y a des fichiers PDF dont les noms ne se terminent pas .pdf, alors votre pédanterie sera très appréciée. Mais c'est une situation relativement inhabituelle (malgré votre travail) et nous n'avons aucune raison de croire que le demandeur doit réellement y faire face, donc je pense que l'argument que vous faites, bien que valide, est un peu distrayant - et je pense que la façon énergique que vous avez formulée pousse la réponse dans le domaine du "(probablement) pas utile". (Mon opinion seulement, bien sûr.)
David Z

Puisque nous sommes pédant, comment géreriez- vous les fichiers PDF tels que les polyglottes PoC || GTFO ?
Stephen Kitt

@StephenKitt - Je ne sais pas ce que vous demandez, mais je suis intrigué. Ils ressemblent à des PDF ordinaires avec des noms pas particulièrement géniaux. Est-ce que cela échouerait ma solution suggérée?
Rich

@DavidZ Je ne sais pas quoi dire à cela. Je veux dire, n'est-ce pas un peu pédant de souligner que je suis pédant alors que j'en ai déjà dit autant? Voici pourquoi ce n'est "pas utile": une bonne solution pour trouver des PDF devrait être une solution adaptable pour trouver des scripts, des exécutables binaires, des bibliothèques, des fichiers multimédias, etc. Je ne peux même pas commencer à voir comment j'adapterais l'un des d'autres réponses pour "exécutables compressés Mach", mais je suis prêt à apprendre.
Rich

1
@ Beaucoup de fichiers PDF sont également des fichiers ZIP, certains sont également des images ou même des machines virtuelles amorçables ... (Voir les liens «spoilers» sur les premiers numéros pour des conseils; le reste est documenté dans les PDF eux-mêmes.)
Stephen Kitt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.