Trova tutti i PDF con almeno tre caratteri nel loro nome


9

Vorrei trovare i file PDF il cui nome (esclusa l'estensione) è maggiore di tre.

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

non restituisce nulla, ma

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

lavori.

Come posso abilitare la {3,}variante?


Che lunghezza? Lunghezza del nome file? Lunghezza della pagina?
Ignacio Vazquez-Abrams,

Risposte:


18

Supponendo che tu stia usando GNU find(cosa che probabilmente sei, dal momento che -iregexè un'estensione GNU a POSIXfind ), -regexe di -iregexdefault le espressioni regolari di Emacs, che non riconoscono {3,}. È necessario specificare un diverso tipo di espressioni regolari utilizzando l' -regextypeopzione; inoltre, devi adattare la tua espressione regolare al fatto che l'espressione corrisponde al percorso completo:

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

Dovresti anche sfuggire a in .modo che corrisponda a "." piuttosto che qualsiasi personaggio:

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

L'espressione regolare può essere semplificata poiché ci preoccupiamo solo di tre caratteri non "/":

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

Per completezza, con FreeBSD o NetBSD find(un'altra implementazione che supporta -iregex, non la tua anche se .+non funzionerebbe lì senza -E), dovresti scrivere:

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

o:

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

Senza -E, questa è un'espressione regolare di base (come in grep) e con -E un'espressione regolare estesa (come in grep -E).

Con ast-open find:

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

(che è esteso regexps out of the box).


20

Qui è più facile con i caratteri jolly standard:

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

O con alcune findimplementazioni (anche quelle che supportano -regexsupportano -iname):

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

Per un numero arbitrario di caratteri anziché 3, è qui che potresti preferire tornare a -iregexdove disponibile (vedi la risposta di @Stephen Kitt ) o potresti usare zsho ksh93globs:

  • zsh:

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

    (il (D)da considerare file nascosti e file in directory nascoste come con find)

    • (#cx,y)è l' zshequivalente jolly di regexp{x,y}
    • (#i) per maiuscole e minuscole
    • ?carattere jolly standard per ogni singolo carattere (come regexp .)
    • **/: qualsiasi livello di sottodirectory (incluso 0)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y): operatore jolly esteso ksh simile a regexp (x|y).
    • FIGNORE: variabile speciale che controlla quali file vengono ignorati dai globs. Se impostato, la normale ignorazione dei file nascosti non viene eseguita, ma vogliamo comunque ignorare le voci di directory .e ..dove presenti.
    • {x,y}(z)è ksh93l'equivalente di regexp z{x,y}.
    • ~(i:...): corrispondenza senza distinzione tra maiuscole e minuscole.

I globi hanno alcuni vantaggi extra findqui in quanto si ottiene un elenco ordinato (è possibile disabilitare tale ordinamento zshcon il oNqualificatore glob o utilizzare diversi criteri di ordinamento) e funziona anche quando i nomi dei file contengono una sequenza di byte che non formano caratteri validi (per ad esempio, in una locale che utilizza il set di caratteri UTF-8, l' findapproccio non riuscirebbe a riportare un $'St\xE9phane Chazelas - CV.pdfdato che \xE9non essendo un carattere non corrisponde a regexp .o jolly ?o *con GNU find).


Funzionerebbe per Bash? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea,

7

Come faccio a sapere se sono PDF?

Non lo fai a meno che non lo chieda. Certo, sono pedante, ma non hai chiesto informazioni sui file con i .pdfloro nomi . Solo perché un file ha i caratteri .pdfnel nome file non lo rende un file PDF .

In effetti, siamo completamente pedanti su questo: se gli ultimi quattro caratteri del nome di un file sono .pdf, allora avrà sempre più di tre caratteri nel suo nome .

Quindi facendo questo nel modo sbagliato , potresti dire:

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

Vedi quella seconda? In realtà è un eseguibile. (Lo so, ho cambiato il nome.) E mi manca anche un PDF che avrei potuto giurare fosse nella directory Documents ...

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

Quindi usando -inamequesto potremmo trovare quello, ma questo sta ancora alzando questo file non PDF.

Quello che vogliamo veramente fare in questo caso è esaminare il numero magico del file usando il filecomando. Un'opzione genera il tipo MIME , che è più semplice da analizzare. La findquery diventa quindi semplice -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

Usiamo il delimitatore dei due punti e cerchiamo il tipo MIME application/pdf, quindi azzeriamo quella parte e stampiamo il risultato. Prendi nota, uno dei miei file ha due punti nel nome; quindi non posso semplicemente chiedere a Awk di farlo ($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

Ora finiamo con l'idea di includere file PDF denominati ae 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

È tutto. So che probabilmente sarò offeso per essere orribilmente pedante, ma nel mio lavoro con migliaia di volumi NFS da cacciare e tutti i tipi di file scarsamente nominati, vorrei che più persone fossero pedanti.

Modificato per aggiungere: nel mondo reale, potrei voler usare updatedbper costruire un indice di file ricercabile, locateinvece di findleggere quell'indice, e parallelinvece di xargsfare il thread up. Questo è in qualche modo al di fuori dell'ambito di questa domanda. L'ho scritto anche con una faccia seria. Perché mi interessa così tanto? Potrei cercare film e file audio; o alcuni tipi di fotografie; o eseguibili binari in una directory di dati di progetto.


1
Se il richiedente ha la stessa situazione in cui ci sono, dove ci sono file PDF i cui nomi non finiscono .pdf, allora la tua pedanteria sarà molto apprezzata. Ma è una situazione relativamente insolita (nonostante il tuo lavoro) e non abbiamo alcun motivo per credere che il richiedente in realtà debba occuparsene, quindi penso che il punto che stai sollevando, seppur valido, sia fonte di distrazione - e penso che il modo in cui hai espresso la frase spinga la risposta nel regno di "(probabilmente) non utile". (Solo la mia opinione, ovviamente.)
David Z,

Dal momento che siamo pedanti, come gestiresti PDF come i poliglotti PoFO || GTFO ?
Stephen Kitt,

@StephenKitt - Non so cosa mi stai chiedendo ma sono incuriosito. A me sembrano dei normali PDF con nomi non particolarmente funky. Questi fallirebbero la mia soluzione suggerita?
Ricco

@DavidZ Non sono sicuro di cosa dire. Voglio dire, non è un po 'pedante sottolineare che sono pedante quando ho già detto tanto? Ecco perché non è "non utile": una buona soluzione per trovare PDF dovrebbe essere una soluzione adattabile per trovare script, eseguibili binari, librerie, file multimediali, ecc. Non riesco nemmeno a vedere come adatterò uno dei altre risposte per "eseguibili Mach compressi", ma sono disposto a imparare.
Ricco

1
@ Molti dei PDF sono anche file ZIP, alcuni sono anche immagini, o anche macchine virtuali avviabili ... (Vedi i link "spoiler" sui primi numeri per suggerimenti; il resto è documentato nei PDF stessi.)
Stephen Kitt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.