Angenommen, Sie verwenden GNU find(was Sie wahrscheinlich sind, da -iregexes sich um eine GNU-Erweiterung für POSIX handeltfind ) -regexund -iregexstandardmäßig reguläre Emacs-Ausdrücke, die nicht erkannt werden {3,}. Mit der -regextypeOption müssen Sie einen anderen Typ regulärer Ausdrücke angeben . Darüber hinaus müssen Sie Ihren regulären Ausdruck an die Tatsache anpassen, dass der Ausdruck mit dem vollständigen Pfad übereinstimmt:
Der Vollständigkeit halber würden Sie mit FreeBSD oder NetBSD find(eine andere Implementierung, die unterstützt -iregex, aber nicht Ihre, da .+sie dort nicht funktionieren -Ewürde) schreiben:
find ~ -iregex '.*[^/]\{3\}\.pdf'
oder:
find -E ~ -iregex '.*[^/]{3}\.pdf'
Ohne -Eist das ein grundlegender regulärer Ausdruck (wie in grep) und mit einem -Eerweiterten regulären Ausdruck (wie in grep -E).
Mit Ast-Open find:
find ~ -iregex '.*[^/]{3}\.pdf'
(Das sind erweiterte reguläre Ausdrücke aus der Box).
Oder mit einigen findImplementierungen (diejenigen, die -regexauch unterstützen -iname):
find ~ -iname '*???.pdf'
Wenn Sie eine beliebige Anzahl von Zeichen anstelle von 3verwenden möchten, ziehen Sie es möglicherweise vor, auf die -iregexverfügbaren zurückzugreifen (siehe Antwort von @Stephen Kitt ), oder Sie könnten Folgendes verwenden zshoder ksh93globs:
zsh::
set -o extendedglob # best in ~/.zshrc
printf '%s\n' ~/**/?(#c3,).(#i)pdf(D)
(die (D)versteckten Dateien und Dateien in versteckten Verzeichnissen wie mit zu berücksichtigen find)
(#cx,y)ist das zshPlatzhalteräquivalent von regulärem Ausdruck{x,y}
(#i) für Groß- und Kleinschreibung nicht berücksichtigen
?Standard-Platzhalter für ein einzelnes Zeichen (wie regulärer Ausdruck .)
**/: jede Ebene von Unterverzeichnissen (einschließlich 0)
ksh93::
FIGNORE='@(.|..)' # to consider hidden files
set -o globstar
printf '%s\n' **/{3,}(?).~(i:pdf)
@(x|y): erweiterter ksh-Platzhalteroperator ähnlich wie regulärer Ausdruck (x|y).
FIGNORE: Spezielle Variable, die steuert, welche Dateien von Globs ignoriert werden. Wenn diese Option aktiviert ist, werden versteckte Dateien normalerweise nicht ignoriert. Wir möchten jedoch die Einträge .und, ..sofern vorhanden , ignorieren .
{x,y}(z)ist ksh93das Äquivalent von regulärem Ausdruck z{x,y}.
~(i:...): Groß- und Kleinschreibung wird nicht berücksichtigt.
Globs haben hier einige zusätzliche Vorteile find: Sie erhalten eine sortierte Liste (Sie können diese Sortierung zshmit dem oNGlob-Qualifikationsmerkmal deaktivieren oder andere Sortierkriterien verwenden) und funktionieren auch, wenn Dateinamen eine Folge von Bytes enthalten, die keine gültigen Zeichen bilden (z In einem Gebietsschema, das den UTF-8-Zeichensatz verwendet, würde der findAnsatz beispielsweise a nicht melden $'St\xE9phane Chazelas - CV.pdf, \xE9da kein Zeichen nicht mit regulärem Ausdruck .oder Platzhalter ?oder *mit GNU übereinstimmt find.
Würde das für Bash funktionieren? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
Wjandrea
7
Woher weiß ich, dass es sich um PDFs handelt?
Sie tun es nicht, wenn Sie nicht fragen. Sicher, ich bin pedantisch, aber Sie haben nicht nach Dateien.pdf gefragt, deren Namen enthalten sind . Nur weil eine Datei die Zeichen .pdfim Dateinamen enthält, wird sie nicht zu einer PDF-Datei .
Lassen Sie uns diesbezüglich ganz pedantisch vorgehen: Wenn die letzten vier Zeichen des Dateinamens lauten .pdf, enthält der Name immer mehr als drei Zeichen .
Wenn Sie dies also falsch machen , könnten Sie sagen:
Sehen Sie den zweiten? Es ist eigentlich eine ausführbare Datei. (Ich weiß, ich habe den Namen geändert.) Und ich vermisse auch ein PDF, von dem ich schwören könnte, dass es sich im Dokumentenverzeichnis befindet ...
$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf
Wenn -inamewir also eine verwenden, können wir diese finden, aber diese Nicht-PDF-Datei wird immer noch angezeigt.
Was wir in diesem Fall wirklich tun möchten, ist die magische Nummer der Datei mit dem fileBefehl zu untersuchen. Eine Option gibt den MIME-Typ aus , der einfacher zu analysieren ist. Die findAbfrage wird dann einfach -name "???*".
Verwenden wir das Doppelpunkttrennzeichen, suchen nach dem MIME-Typ application/pdf, setzen diesen Teil auf Null und drucken das Ergebnis. Beachten Sie, dass eine meiner Dateien einen Doppelpunkt im Namen hat. also kann ich nicht einfach awk fragen ($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
Beenden Nun lassen sie durch Einfädeln PDF Dateien mit dem Namen enthalten aund 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
Das ist alles. Ich weiß, dass ich mich wahrscheinlich dafür begeistern werde, schrecklich pedantisch zu sein, aber bei meiner Arbeit mit Tausenden von zu jagenden NFS-Bänden und allen Arten von Dateien mit schlechtem Namen wünschte ich mir, mehr Menschen wären pedantisch.
Bearbeitet, um hinzuzufügen: In der realen Welt möchte ich möglicherweise updatedbeinen durchsuchbaren Dateiindex erstellen, locateanstatt finddiesen Index zu lesen und parallelanstatt ihn xargszu fädeln. Das liegt jedoch etwas außerhalb des Rahmens dieser Frage. Das habe ich auch mit ernstem Gesicht geschrieben. Warum kümmert es mich so sehr? Ich suche möglicherweise nach Film- und Audiodateien. oder bestimmte Arten von Fotografien; oder binäre ausführbare Dateien in einem Projektdatenverzeichnis.
Wenn der Fragesteller die gleiche Situation hat wie Sie, in der es PDF-Dateien gibt, deren Namen nicht enden .pdf, wird Ihre Pedanterie sehr geschätzt. Aber es ist eine relativ ungewöhnliche Situation (trotz Ihres Jobs) und wir haben keinen Grund zu der Annahme, dass der Fragesteller sich tatsächlich damit befassen muss. Ich denke also, dass der Punkt, den Sie machen, zwar gültig, aber irgendwie ablenkend ist - und ich denke, die kraftvolle Art, wie Sie es formuliert haben, drückt die Antwort in den Bereich von "(wahrscheinlich) nicht nützlich". (Nur meine Meinung natürlich.)
David Z
Wie würden Sie mit PDFs wie den PoC || GTFO- Polyglots umgehen, da wir pedantisch sind ?
Stephen Kitt
@ StephenKitt - Unsicher, was Sie fragen, aber ich bin fasziniert. Sie sehen für mich wie gewöhnliche PDFs mit nicht besonders funkigen Namen aus. Würden diese meine vorgeschlagene Lösung verfehlen?
Rich
@ DavidZ Ich bin mir nicht sicher, was ich dazu sagen soll. Ich meine, ist es nicht ein bisschen pedantisch darauf hinzuweisen, dass ich pedantisch bin, wenn ich das schon gesagt habe? Hier ist der Grund, warum es nicht "nicht nützlich" ist: Eine gute Lösung zum Auffinden von PDFs sollte eine anpassbare Lösung zum Auffinden von Skripten, binären ausführbaren Dateien, Bibliotheken, Mediendateien usw. sein. Ich kann nicht einmal erkennen, wie ich eine der Dateien anpassen würde andere Antworten für "komprimierte ausführbare Mach-Dateien", aber ich bin bereit zu lernen.
Rich
1
@Rich viele der PDFs sind auch ZIP-Dateien, einige sind auch Images oder sogar bootfähige virtuelle Maschinen ... (Hinweise finden Sie unter den "Spoiler" -Links in den ersten Ausgaben; der Rest ist in den PDFs selbst dokumentiert.)
Antworten:
Angenommen, Sie verwenden GNU
find
(was Sie wahrscheinlich sind, da-iregex
es sich um eine GNU-Erweiterung für POSIX handeltfind
)-regex
und-iregex
standardmäßig reguläre Emacs-Ausdrücke, die nicht erkannt werden{3,}
. Mit der-regextype
Option müssen Sie einen anderen Typ regulärer Ausdrücke angeben . Darüber hinaus müssen Sie Ihren regulären Ausdruck an die Tatsache anpassen, dass der Ausdruck mit dem vollständigen Pfad übereinstimmt:Sie sollten auch dem entkommen,
.
damit es mit "." Übereinstimmt. eher als irgendein Charakter:Der reguläre Ausdruck kann vereinfacht werden, da wir uns nur um drei Nicht-"/" -Zeichen kümmern:
Der Vollständigkeit halber würden Sie mit FreeBSD oder NetBSD
find
(eine andere Implementierung, die unterstützt-iregex
, aber nicht Ihre, da.+
sie dort nicht funktionieren-E
würde) schreiben:oder:
Ohne
-E
ist das ein grundlegender regulärer Ausdruck (wie ingrep
) und mit einem-E
erweiterten regulären Ausdruck (wie ingrep -E
).Mit Ast-Open
find
:(Das sind erweiterte reguläre Ausdrücke aus der Box).
quelle
Hier ist es mit Standard-Platzhaltern einfacher:
Oder mit einigen
find
Implementierungen (diejenigen, die-regex
auch unterstützen-iname
):Wenn Sie eine beliebige Anzahl von Zeichen anstelle von
3
verwenden möchten, ziehen Sie es möglicherweise vor, auf die-iregex
verfügbaren zurückzugreifen (siehe Antwort von @Stephen Kitt ), oder Sie könnten Folgendes verwendenzsh
oderksh93
globs:zsh
::(die
(D)
versteckten Dateien und Dateien in versteckten Verzeichnissen wie mit zu berücksichtigenfind
)(#cx,y)
ist daszsh
Platzhalteräquivalent von regulärem Ausdruck{x,y}
(#i)
für Groß- und Kleinschreibung nicht berücksichtigen?
Standard-Platzhalter für ein einzelnes Zeichen (wie regulärer Ausdruck.
)**/
: jede Ebene von Unterverzeichnissen (einschließlich 0)ksh93
::@(x|y)
: erweiterter ksh-Platzhalteroperator ähnlich wie regulärer Ausdruck(x|y)
.FIGNORE
: Spezielle Variable, die steuert, welche Dateien von Globs ignoriert werden. Wenn diese Option aktiviert ist, werden versteckte Dateien normalerweise nicht ignoriert. Wir möchten jedoch die Einträge.
und,..
sofern vorhanden , ignorieren .{x,y}(z)
istksh93
das Äquivalent von regulärem Ausdruckz{x,y}
.~(i:...)
: Groß- und Kleinschreibung wird nicht berücksichtigt.Globs haben hier einige zusätzliche Vorteile
find
: Sie erhalten eine sortierte Liste (Sie können diese Sortierungzsh
mit demoN
Glob-Qualifikationsmerkmal deaktivieren oder andere Sortierkriterien verwenden) und funktionieren auch, wenn Dateinamen eine Folge von Bytes enthalten, die keine gültigen Zeichen bilden (z In einem Gebietsschema, das den UTF-8-Zeichensatz verwendet, würde derfind
Ansatz beispielsweise a nicht melden$'St\xE9phane Chazelas - CV.pdf
,\xE9
da kein Zeichen nicht mit regulärem Ausdruck.
oder Platzhalter?
oder*
mit GNU übereinstimmtfind
.quelle
shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
Woher weiß ich, dass es sich um PDFs handelt?
Sie tun es nicht, wenn Sie nicht fragen. Sicher, ich bin pedantisch, aber Sie haben nicht nach Dateien
.pdf
gefragt, deren Namen enthalten sind . Nur weil eine Datei die Zeichen.pdf
im Dateinamen enthält, wird sie nicht zu einer PDF-Datei .Lassen Sie uns diesbezüglich ganz pedantisch vorgehen: Wenn die letzten vier Zeichen des Dateinamens lauten
.pdf
, enthält der Name immer mehr als drei Zeichen .Wenn Sie dies also falsch machen , könnten Sie sagen:
Sehen Sie den zweiten? Es ist eigentlich eine ausführbare Datei. (Ich weiß, ich habe den Namen geändert.) Und ich vermisse auch ein PDF, von dem ich schwören könnte, dass es sich im Dokumentenverzeichnis befindet ...
Wenn
-iname
wir also eine verwenden, können wir diese finden, aber diese Nicht-PDF-Datei wird immer noch angezeigt.Was wir in diesem Fall wirklich tun möchten, ist die magische Nummer der Datei mit dem
file
Befehl zu untersuchen. Eine Option gibt den MIME-Typ aus , der einfacher zu analysieren ist. Diefind
Abfrage wird dann einfach-name "???*"
.Verwenden wir das Doppelpunkttrennzeichen, suchen nach dem MIME-Typ
application/pdf
, setzen diesen Teil auf Null und drucken das Ergebnis. Beachten Sie, dass eine meiner Dateien einen Doppelpunkt im Namen hat. also kann ich nicht einfach awk fragen($2==":"){print $1}
.Beenden Nun lassen sie durch Einfädeln PDF Dateien mit dem Namen enthalten
a
undabc
:Das ist alles. Ich weiß, dass ich mich wahrscheinlich dafür begeistern werde, schrecklich pedantisch zu sein, aber bei meiner Arbeit mit Tausenden von zu jagenden NFS-Bänden und allen Arten von Dateien mit schlechtem Namen wünschte ich mir, mehr Menschen wären pedantisch.
Bearbeitet, um hinzuzufügen: In der realen Welt möchte ich möglicherweise
updatedb
einen durchsuchbaren Dateiindex erstellen,locate
anstattfind
diesen Index zu lesen undparallel
anstatt ihnxargs
zu fädeln. Das liegt jedoch etwas außerhalb des Rahmens dieser Frage. Das habe ich auch mit ernstem Gesicht geschrieben. Warum kümmert es mich so sehr? Ich suche möglicherweise nach Film- und Audiodateien. oder bestimmte Arten von Fotografien; oder binäre ausführbare Dateien in einem Projektdatenverzeichnis.quelle
.pdf
, wird Ihre Pedanterie sehr geschätzt. Aber es ist eine relativ ungewöhnliche Situation (trotz Ihres Jobs) und wir haben keinen Grund zu der Annahme, dass der Fragesteller sich tatsächlich damit befassen muss. Ich denke also, dass der Punkt, den Sie machen, zwar gültig, aber irgendwie ablenkend ist - und ich denke, die kraftvolle Art, wie Sie es formuliert haben, drückt die Antwort in den Bereich von "(wahrscheinlich) nicht nützlich". (Nur meine Meinung natürlich.)