と**/*.ext
一致するすべてのサブディレクトリのすべてのファイルに展開することはわかってい*.ext
ますが、現在のディレクトリにあるそのようなすべてのファイルを含む同様の展開とは何ですか?
回答:
これはBash 4で機能します。
ls -l {,**/}*.ext
ダブルアスタリスクのグロブが機能するためには、globstar
オプションを設定する必要があります(デフォルト:オン):
shopt -s globstar
からman bash
:
グロブスター 設定されている場合、ファイル名展開で使用されるパターン** テキストはファイルと0個以上のディレクトリに一致し、 サブディレクトリ。パターンの後に/が続く場合は、 ディレクトリとサブディレクトリが一致しています。
今は、globstarの処理にバグがあったのではないかと思っls **/*.ext
ています。これは、単に使用すると正しい結果が得られるためです。
とにかく、私はkenorbがVLCリポジトリを使用して行った分析を見て、その分析にいくつかの問題を見つけました。
find
コマンドの出力との比較は、指定-type f
に他のファイルタイプ(特にディレクトリ)が含まれておらず、ls
リストされているコマンドにも含まれている可能性があるため、無効です。また、リストされたコマンドの1つ(ls -1 {,**/}*.*
上記のものに基づいているように見える)は、サブディレクトリにあるファイルのドットを含む名前のみを出力します。OPの質問と私の答えには、特定の拡張子を持つファイルが求められているため、ドットが含まれています。
ただし、最も重要なのはls
、globstarパターンを使用したコマンドを使用する特別な問題があることです**
。パターンがBashによって検査中のツリー内のすべてのファイル名(およびディレクトリ名)に拡張されるため、多くの重複が発生します。展開に続いて、ls
コマンドはそれらのそれぞれと、それらがディレクトリーである場合はその内容をリストします。
例:
現在のディレクトリには、サブディレクトリA
とその内容があります。
A
└── AB
└── ABC
├── ABC1
├── ABC2
└── ABCD
└── ABCD1
そのツリーで、**
「AA / AB A / AB / ABC A / AB / ABC / ABC1 A / AB / ABC / ABC2 A / AB / ABC / ABCD A / AB / ABC / ABCD / ABCD1」に展開されます(7エントリ) 。これを行うecho **
と、正確な出力が得られ、各エントリが1回表示されます。ただし、これを行うls **
と、それらの各エントリのリストが出力されます。したがって、基本的にはがls A
続くls A/AB
ため、A/AB
2回表示されます。また、ls
各サブディレクトリの出力を個別に設定します。
...
<blank line>
directory name:
content-item
content-item
したがって、を使用するとwc -l
、これらの空白行とディレクトリ名セクションの見出しがすべてカウントされ、カウントがさらに離れます。
これは、解析しls
てはならないもう1つの理由です。
このさらなる分析の結果、この方法でファイルのツリーを反復処理する以外の状況では、globstarパターンを使用しないことをお勧めします。
for entry in **
do
something "$entry"
done
最後の比較として、私が持っていたBashソースリポジトリを使用してこれを行いました。
shopt -s globstar dotglob
diff <(echo ** | tr ' ' '\n') <(find . | sed 's|\./||' | sort)
0a1
> .
私が使用tr
何名にスペースが含まれていないので、ここでの唯一の有効な改行にスペースを変更します。以前sed
は、./
からの出力の各行の先頭を削除していましたfind
。find
通常はソートされておらず、Bashのグロブの展開はすでにソートされているため、出力をソートしました。ご覧のとおり、からの唯一の出力diff
は、による現在のディレクトリ.
出力find
でした。私が行っls ** | wc -l
たとき、出力はほぼ2倍の行数でした。
globstar
が、デフォルトになっていますoff
**/*.ext
でも十分だと思います。また、でない限り、隠しファイルはありませんshopt -s dotglob
。
globstar
:shopt -u globstar
。
**/*.ext
は十分ではありません
このwilは、現在のディレクトリと '.ext'で終わるサブディレクトリにあるすべてのファイルを出力します。
find . -name '*.ext' -print
次を使用**/*.*
して、すべてのファイルを再帰的に含めることができます(有効にする方法:)shopt -s globstar
。
他のバリエーションのテストとその動作を以下で確認してください。
サンプルVLCリポジトリフォルダー内の3472ファイルを含むテストフォルダー:
(につきとしてカウント3472の合計ファイル:find . -type f | wc -l
)
ls -1 **/*.*
-3338を返しますls -1 {,**/}*.*
-3341を返します(Dennisの提案に従います)ls -1 {,**/}*
-8265を返しますls -1 **/*
-隠しファイルを除いて7817を返します(Dennisの提案による)ls -1 **/{.[^.],}*
-7869を返します(Dennisの提案に従います)ls -1 {,**/}.?*
-15855を返しますls -1 {,**/}.*
-20321を返しますしたがって、すべてのファイルを再帰的に一覧表示する最も近い方法は、gniourf-gniourfコメント(ファイルに適切な拡張子があるか、特定の拡張子を使用していると想定**/*.*
)の最初の例()であると思います。 :
$ diff -u <(ls -1 {,**/}*.*) <(ls -1 **/*.*)
--- /dev/fd/63 2015-04-19 15:25:07.000000000 +0100
+++ /dev/fd/62 2015-04-19 15:25:07.000000000 +0100
@@ -1,6 +1,4 @@
COPYING.LIB
-COPYING.LIB
-Makefile.am
Makefile.am
@@ -45,7 +43,6 @@
compat/tdestroy.c
compat/vasprintf.c
configure.ac
-configure.ac
もう1つはさらに重複を生成します。
隠しファイルを含めるには、次を使用しますshopt -s dotglob
(無効にするshopt -u dotglob
)。mv
またはなどのコマンドに影響を与える可能性がありrm
、誤って間違ったファイルを削除する可能性があるため、お勧めしません。
**/*.*
)は有益であり、最も効果的に機能しました。受け入れられた回答により、最上位ディレクトリにアイテムの重複が発生しました。私の作業パターンは次のとおりでした:"${path}"**/*.*
$ find . -type f
現在のディレクトリにあるすべてのファイルが一覧表示されます。次に、-execを使用して、出力に対して他のコマンドを実行できます。
$find . -type f -exec grep "foo" {} \;
文字列「foo」の検索結果から各ファイルをgrepします。
find . -type f
、現在のディレクトリだけでなく、現在のディレクトリのルートを再帰的に適用する誰かが指摘する時かもしれません。
**/*.ext
。それはあなたのために機能しますか?