名前に3文字以上を含むすべてのPDFを見つけます。

名前に3文字以上を含むすべてのPDFを見つけます。

名前(拡張子を除く)が3より大きいPDFファイルを探したいです。

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

何も返さないけど

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

働く

このバリエーションを有効にするには{3,}

答え1

ここでは、標準のワイルドカードを使用する方が簡単です。

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

またはいくつかの実装を介してfind(サポートされている実装-regexもサポート-iname):

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

代わりに、文字数に関係なく利用可能な場所3に戻すことをお勧めします(参照-iregex@Stephen Kittの返信)または以下を使用またはglobすることができzshますksh93

  • zsh:

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

    (D)隠しファイルと次の隠しディレクトリにあるファイルを考えてみてくださいfind

    • (#cx,y)zsh正規表現に対応するワイルドカードです。{x,y}
    • (#i)大文字と小文字を区別しない場合
    • ?単一文字標準ワイルドカード (例: regexp .)
    • **/:すべてのレベルサブディレクトリ(レベル0を含む)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y):regexpに似た拡張kshワイルドカード演算子です(x|y)
    • FIGNORE:グローバルに無視されるファイルを制御する特殊変数。一度設定すると、隠しファイルは通常無視されますが、まだ存在するディレクトリエントリを無視しようとします...
    • {x,y}(z)ksh93regexpと同じですz{x,y}
    • ~(i:...):大文字と小文字を区別しない一致です。

Globはソートされたリストを取得し(glob修飾子を使用してfindソートを無効にするか、他のソート基準を使用できます)、ファイル名に有効な形式を形成しないバイトシーケンスを含む場合でも、いくつかの追加の利点がありますあります。文字操作(UTF-8文字セットを使用するロケールでは、この方法ではaを非文字として報告できないため、正規表現、ワイルドカード、またはGNUと一致しません。zshoNfind$'St\xE9phane Chazelas - CV.pdf\xE9.?*find

答え2

あなたがGNUを使用しているとします(GNUの拡張findなので、おそらくそうです)。-iregexPOSIXfind)、デフォルトはEmacs正規表現に設定されており、-regexこれ-iregexは認識されません{3,}。また、このオプションを使用して他の種類の正規表現を指定し、パス全体に一致する-regextypeように正規表現を調整する必要があります。

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

.また、「.」と一致するようにエスケープする必要があります。文字の代わりに:

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

「/」ではなく、3つの文字しか考慮されないため、正規表現を単純化できます。

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

完全性を期すために、FreeBSDまたはNetBSD(あなたのものではありませんがfindサポートされている別の実装)の場合は、次のように書くことができます。-iregex.+-E

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

または:

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

いいえ-E、それは基本正規表現(例grep:)と-E 拡張正規表現(図grep -E)。

ast-openを使うfind

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

(これは基本的に拡張された正規表現です。)

答え3

PDFかどうかはどうすればわかりますか?

あなたが尋ねない限り、あなたはしません。もちろん私は賢く言うが、あなたは尋ねなかった。ファイル.pdf名には以下が含まれます。.pdfファイル名に文字があるのでPDFファイルにしないでください

実際、これについてずっと賢く考えてみましょう:ファイル名の最後の4文字があれば.pdf名前には常に3文字以上の文字が含まれています。

だからこうやって間違った方法、次のように言うこともできます。

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

二度目も見ましたか?実際に実行可能なファイルです。 (知っています、名前を変更しました。)そしてPDFファイルも失われました。誓うことができるドキュメントディレクトリにあります...

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

したがって、-inameファイルを見つけることができますが、PDF以外のファイルはまだ表示されます。

私たち本物この場合の対処方法は、ファイルの内容を確認することです。マジックナンバーfileコマンドを使用してください。オプション出力MIMEタイプ、解析する方が簡単です。これによりクエリがfind簡単になります-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

コロン区切り文字を使用してMIMEタイプを見つけて、そのapplication/pdf部分をゼロにして結果を印刷しましょう。私のファイルの1つに名前にコロンがあるので、ただ尋ねることはできません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

aそれでは、次の名前のPDFファイルを含めてみましょう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

それはすべてです。とても賢いと非難されるかもしれないことを知っているが、私の作品に何千ものNFSボリュームと名前が違うさまざまなファイルに触れ、より多くの人が賢明になれば幸いです。

編集が追加されました:実際の世界では、それを利用してそのインデックスをスレッド化するのではなく、そのインデックスを読み取るのではなく、検索可能なupdatedbファイルインデックスを構築したい場合があります。しかし、これはこの質問の範囲をわずかに超えています。私も正色に書いています。私はなぜそんなに気にするのですか?プロジェクトのデータディレクトリで、映画やオーディオファイル、特定の種類の写真、またはバイナリ実行可能ファイルを探している可能性があります。locatefindparallelxargs

関連情報