

ディレクトリを再帰的に表現したいときなどに `**` という表記が、なんの説明もなく、あたかも当然のように使われるのですが、この記法はなんでしょうか？
正規表現ではなさそうですし。

例:  
[Spring Securityでユーザ認証を実装してみる -
ももいろテクノロジー](http://inaz2.hatenablog.com/entry/2017/04/18/222721)

>
[code]

>     .antMatchers("/**").hasRole("USER")
>  
[/code]

[Wildcard Mappings](https://struts.apache.org/core-developers/wildcard-
mappings.html)

>
[code]

>     **    Matches zero or more characters including the slash (‘/’)
> character.
>  
[/code]

多くの例では `*` はワイルドカードと呼ばれている気がしますが、発祥はシェルでしょうか？

正規表現であれば、`*` の他にも `^` や `$`
が使えるのではないかと推測がききますが（正規表現の書き方の流派は何種類かあるはずだけど）、同じように、この正規表現ではない`*`が使われていた場合は、他の記号で何が使えそうだというような推測をきかせたりできるものなのでしょうか？


CC BY-SA 4.0
2020-08-08T01:45:10.230
69351
2020-08-11T23:10:11.820
2020-08-08T07:24:47.720
3060
9008
question
linux apache spring-security
ディレクトリの指定などに使われるアスタリスク2つの記法は何を表す？


> ディレクトリを再帰的に表現したいときなどに ** という表記が、なんの説明もなく、あたかも当然のように使われるのですが、この記法はなんでしょうか？
> 正規表現ではなさそうですし。

私は「antのファイルセットの指定時に使えるワイルドカード」の応用だと思います。※`**`の表現を初めて見たのがantだったからというのが理由ですが。  
正規表現の`*`は単独では使われませんので、正規表現とは別物と考えた方がよいでしょう。  
単独の`*`はグロブ(glob)のワイルドカードが由来だと思います。`**`はその拡張ではないでしょうか(推測です)。  
`*`は`/`を含まない任意の文字列、`**`は`/`を含むという説明を見たことがあります。  
ファイルのパスの区切り文字が`/`のとき、`**`はディレクトリをまたがってマッチするので、ディレクトリ直下および配下のディレクトリ下のファイルにマッチさせたいときに指定するワイルドカードだと割り切って使っています。


CC BY-SA 4.0
2020-08-08T05:35:01.613
69357
2020-08-08T05:35:01.613
35558
69351
answer


`*`, `?`, `[a-z]` といったファイルやディレクトリの名前のパターン記法はシェルの「パス名展開」(pathname expansion)
あるいは「ファイル名展開」(filename expansion)、そして C 関数のパス名のパターンマッチ (`glob`(3))
が由来だと思います。正規表現ではありません。

パス名展開やパス名のパターンマッチにもいくつかの方言や拡張が存在し、その中でも「`/` も含むあらゆる文字列に一致」する `**` は `rsync`(1)
が由来ではないかと思っています。(根拠や出典などは知らないです)


CC BY-SA 4.0
2020-08-11T09:08:59.707
69457
2020-08-11T09:08:59.707
3061
69351
answer


質問の使われ方例とはちょっと違うようですが、zshが起源らしいです。  
記事のタイトルでは「再帰globパターン」、記事中の英文では「recursive directory
search」、そして記事からリンクされているzshのマニュアルでは「Recursive Globbing」となっています。

[再帰globパターン **/ の元祖は zsh
なのか、調べてみた](https://hkoba.hatenablog.com/entry/2016/02/10/230206)

> 最初は ..../ だった！

> Zsh-2.1 で ****/ に変わった

> Zsh-2.2 で **/ になった

> 時に、1992/05/14。 ここまでの経緯を見るに、zsh が元祖ではないか？と私には見えました。

zshのマニュアル  
[14.8.6 Recursive
Globbing](http://zsh.sourceforge.net/Doc/Release/Expansion.html#Recursive-
Globbing)

以下のQ&A記事もタイトルは「recursive globbing」です。

[recursive globbing **/* and */**](https://unix.stackexchange.com/q/478933)

> I am learning the wildcards recursive globbing and tried

ここの回答と下記コメントに後述されたリンク先では'**'は「globstar」あるいは「globstar expansion」と言われているようです。

> Also beware that in `zsh`(the original implementation of recursive
> globbing), ...only `**/` is (short for `(*/)#`)... See [The result of ls * ,
> ls ** and ls ***](https://unix.stackexchange.com/q/62660) for details.

そして上記いずれの記事/マニュアル/コメントにも、`**/`は`(*/)#`の短縮形であると書かれてて、`#`はzshマニュアルのGlob
Operatorsという項目で正規表現の`*`と同様の仕様(直前のパターンの0回以上の繰り返し)となっています。  
だから正規表現(の方言?)と言うことも出来そうです。

[14.8.1 Glob
Operators](http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-
Operators) の最後の方

> x#
>
> (Requires EXTENDED_GLOB to be set.) Matches zero or more occurrences of the
> pattern x. This operator has high precedence; '12#' is equivalent to
> '1(2#)', rather than '(12)#'.

* * *

質問や他回答に出てくるものの初出がだいたいzshよりも後なので、まあzsh起源と言っても良いのでしょう。  
httpdのApacheが1995, rsyncが1996, Apache Antが2000, Spring Frameworkが2002です。

'**'はrsyncに解説込みで、Apache Antにbuild.xmlの1行で、出ています。

[rsync(1) - Linux man page](https://linux.die.net/man/1/rsync)  
[Apache Ant - Wikipedia](https://en.wikipedia.org/wiki/Apache_Ant)

* * *

ちなみにPythonだと3.5からのサポートなので割と最近です。  
[glob --- Unix 形式のパス名のパターン展開](https://docs.python.org/ja/3/library/glob.html)

> glob.glob(pathname, *, recursive=False)  
>  recursive が真の場合、パターン "**"
> はあらゆるファイルや0個以上のディレクトリ、サブディレクトリおよびディレクトリへのシンボリックリンクにマッチします。  
>  バージョン 3.5 で変更: "**" を使った再帰的な glob がサポートされました。

globでは再帰するか否かはオプションですが、pathlibでは決め打ちで再帰します。  
[pathlib ---
オブジェクト指向のファイルシステムパス](https://docs.python.org/ja/3/library/pathlib.html)

> パターン "**" は "このディレクトリおよびすべてのサブディレクトリを再帰的に走査" を意味します。言い換えれば、再帰的な Glob
> 走査が可能という意味です:

* * *

ファイル名のワイルドカードとしての起源は1960年代のようです。  
CTSSが1961, TOPS-10が1967, MulticsとUNIXが1969です。

[Earliest use of an asterisk (*) to indicate a zero-to-many character
wildcard?](https://english.stackexchange.com/q/118417)  
1956年頃の正規表現が元になっているというコメント

> It was invented by Stephen Kleene around 1956 as part of the specifications
> for [regular expressions](http://en.wikipedia.org/wiki/Regular_expression);
> it's called the ["Kleene star" or the "Kleene
> closure"](http://en.wikipedia.org/wiki/Kleene_star). – John Lawler Jul 4 '13
> at 23:25

回答ではTOPS-10とMulticsが元だと引用されています。

> >   1. History of the asterisk wildcard character leading up to DOS and UNIX
> (and beyond):
>>

>>

>> TOPS-10 syntax (precursor of MS-DOS)

>>

>> Multics syntax (precursor of UNIX and modern Microsoft Windows)

もう一つCTSSにもワイルドカードという概念はあったようです。  
[Compatible Time-Sharing System -
Wikipedia](https://en.wikipedia.org/wiki/Compatible_Time-Sharing_System)

>   * delete – Delete file, had * wildcards
>

UNIXの方は、こちらの「起源」の項目に記述がありますが、「インタプリタとは独立した`/etc/glob`というプログラム」が最初のようです。  
[グロブ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AD%E3%83%96)


CC BY-SA 4.0
2020-08-11T13:08:47.330
69461
2020-08-11T23:10:11.820
2020-08-11T23:10:11.820
26370
26370
69351
answer