ファイル名の範囲に基づいてファイルを見つける方法は?

ファイル名の範囲に基づいてファイルを見つける方法は?

2341a.po、などの4567211someword.po数値名を持つファイルがあります。0012.po数値範囲に基づいてファイルセットを探したいです。たとえば[126 - 363]

通常、私は正規表現を使用しますfind。すべての数値範囲は、2つの正規表現で構成できます[N, M]larger than Nless than M

Nより大きい:

もしそうなら、まずは誰にでもN = vxyzマッチします。value > V000, (V=v+1)[V-9]\d{3,}

次にvX00、、、、X=x+1v[X-9]\d\d

次にvxY0、、、、Y=y+1vx[Y-9]\d

ついにvxy[z-9]

例:

一致させるには、number>=234次を使用します。

`^(0*([3-9]\d{2,}|2[4-9]\d|23[4-9]))`

M未満:

同様のロジックに基づいて、次のような結果が得られます。

^(0*(vxy[0-z]|vx[0-Y]\d|v[0-X]\d\d|[1-V]\d\d|\d{1,3}))[^0-9]

そしてY=y-1,X=x-1,V=v-1

たとえば、次のコマンドは [253, 326] の間のすべてのファイルを検索します。

find . -maxdepth 1 -type f -regextype posix-extended -iregex '^\./0*([3-9][0-9]{2,}|2[6-9][0-9]{2,}|25[3-9]).*' -iregex '^\./0*(32[0-6]|3[0-1][0-9]|[0-2][0-9][0-9]|[0-9]{1,2})[^0-9].*'

しかし、このアプローチは長い数字を扱うにはあまりにも迷惑です。これを行うより良い簡単な方法はありますか?

答え1

そしてzsh

setopt extendedglob # best in ~/.zshrc
ls -ld -- <126-253>(*.po~[0-9]*)

つまり、10進数126〜253(000126も許可されています)、その後に.po10進数で終わり、10進数で始まらない数字が続きます。

隠しディレクトリと通常のファイルのみを含む再帰的に:

ls -ld -- **/<126-253>(*.po~[0-9]*)(D.)

会っzargsたらarg list too long間違い。

リテラル数の代わりに変数を使用したい場合は、これを行うことはできません<$low-$high>。この<x-y>演算子は、リダイレクト演算子(echo <3-4> zPOSIXシェルではファイルechoから3-リダイレクトされた入力として実行され、fd 4で入力z)と重なり、zshリテラル数だけを許可して競合のリスクを最小限に抑えるようにします。ただし、この演算子をglobsubsting拡張の一部として使用できます。たとえば、次のようになります。

low=126 high=253
ls -ld -- ${~:-"<$low-$high>"}(*.po~[0-9]*)

有効${~expansion}globsubst拡張にワイルドカードを使用することを許可)は、任意の拡張を拡張できるようにする特別な形式expansionです。${:-"text"}${var:-default}text

答え2

検索したい数字を含むファイルのリストを作成し、それをパラメータリストに入れてfind使用できますxargs。たとえば、質問で使用するのと同じことは次のとおりですbash-maxdepth 1

echo {253..326} | xargs sh -c 'find "$@" -type f -maxdepth 0' sh

-Iオプションxargs(例xargs -I{} find {} -type f)を使用できますが、GNUはこのオプションをxargs強制します-L 1。つまり、各引数に対して別々の照会プロセスを開始することを意味します。使用すると、shこの問題を解決できます。

どんな深さでも次のことができます。

printf -- '-o -name %d ' {254..326} |
  xargs -n 3000 sh -c 'find -type f \( -name 253 "$@" \)' sh

パラメータ-n(コマンドごとに追加される最大パラメータ数)は、パラメータリスト構造のサイズが制限されるように選択する必要がありますxargs。大きすぎると、パラメータ数ではなくパラメータリストの合計サイズが制限に達する可能性があります。-oリストに次のorが残らないように3の倍数でなければなりません。-name

答え3

Graemeの答えへの強力な拡張:

find . -type f -regextype posix-awk -regex ".*/0*($(seq -s'|' 254 456)).*" 

POSIXが必要な場合は\|代わりに使用できます|(しかしPOSIXではありませんか?)。\(\)()seq

$ find . -maxdepth 2 -type f -regextype posix-awk -regex ".*/0*($(seq -s'|' 254 456)).*"    
./.fontconfig/3047814df9a2f067bd2d96a2b9c36e5a-le32d4.cache-3
./.fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le32d4.cache-3
./.fontconfig/385c0604a188198f04d133e54aba7fe7-le32d4.cache-3
./Documents/374620-63301.pdf
./4567211someword.po

よく。数字の終わりを表示するには、数字以外の文字を追加する必要があるようです。おそらく".*/0*($(seq -s'|' 254 456))[^0-9].*"

答え4

find | perl -ne 'print if(m!^\./(\d+)! and $1 > 126 and $1 <363)'

...他の答えで提案された良いアイデアを追加することもできます。

正規表現には少し調整が必要な場合があります(例^\./(\d+)\w*.po$:)

関連情報