web-dev-qa-db-ja.com

globstar: `** string *`はサブディレクトリに下降しません `** / * string *`は下降します

与えられているのは、次のような文字列に一致する(サブ)ディレクトリ内のファイルのセットです。

_find -name 'string' | sort
./1/2/3/4/string
./1/2/3/string
./1/2/string
./1/string
./string
_

globstarを使用してファイルを照合する理由

_ls **string
string
_

ディレクトリの実行に失敗しますが、

_ls **/string
1/2/3/4/string  1/2/3/string  1/2/string  1/string  string
_

成功しますか? manページの説明の私の理解から、それは(サブ)ディレクトリと一致するはずですよね?

このような質問は通常、 "ls *、ls **お​​よびls ***の結果" の重複としてマークされますが、そこでの回答は_ls **_のみを処理しますが、これは実際に繰り返されます。ディレクトリ。二重アスタリスクの後に文字列が続くと、globstarが壊れるように見えます。

_mint 19_でGNU bash v.4.4.19(1)を実行しています


_man bash_から

globstar

設定されている場合、パス名拡張コンテキストで使用されるパターン**は、すべてのファイルと0個以上のディレクトリおよびサブディレクトリに一致します。パターンの後に/が続く場合、ディレクトリとサブディレクトリのみが一致します。

3
Fiximan

これがKshおよびZshでも機能する方法です。

$ mkdir -p a/b/cdir
$ touch    a/b/cfile
$ ksh -c 'set -o globstar; echo **c*'
**c*
$ zsh -c 'echo **c*'
zsh:1: no matches found: **c*

パターンマッチングの下で​​、Bashのマニュアルには次のように書かれています。

globstar Shellオプションが有効になっている場合、および*は、ファイル名拡張コンテキストで使用され、2つの隣接する*sを単一のパターンとして使用すると、すべてのファイルと0個以上のディレクトリおよびサブディレクトリに一致します。

これは、「単一パターン」がスラッシュで区切られた部分であることを意味していると解釈できると思います。したがって、foo/**/barは単一のパターンでそれを持っていますが、**barしません。

しかし、それはもっと明確かもしれません。

パターン全体の後に続くスラッシュは、パターンをディレクトリだけに一致させます。

$ echo **/c*/
a/b/cdir/
2
ilkkachu

二重の*は、(のみ)*によって制限されていない場合、1つの/の効果に減衰します。

$ ls *c
abc  ac  acc  bc  cc  dc

$ ls **c
abc  ac  acc  bc  cc  dc

/以外の先頭または末尾の文字は、**を減衰させます。

これは、パス名(ファイル名として)に/を含めることができるためですnot
*/を含む名前に展開することはできません。 **は多少似ていますが、単独で、または/で区切られている場合(他の文字/文字列ではない)、/のみを含む文字列に展開されます。

$ ls -d ./** | sort
./
./1
./1/2
./1/2/3
./1/2/3/4
./1/2/3/4/string
./1/2/3/string
./1/2/string
./1/string
./abc
./ac
./acc
./bc
./cc
./dc
./string

$ ls -d ./**c | sort 
./abc
./ac
./acc
./bc
./cc
./dc

$ ls -d ** | sort
1
1/2
1/2/3
1/2/3/4
1/2/3/4/string
1/2/3/string
1/2/string
1/string
abc
ac
acc
bc
cc
dc
string

$ ls -d **c | sort
abc
ac
acc
bc
cc
dc

$ ls -d **/ | sort
1/
1/2/
1/2/3/
1/2/3/4/

$ ls -d 1**/ | sort
1/
1
Isaac