パターンに一致するファイル名を含むディレクトリ名を一覧表示するには?

パターンに一致するファイル名を含むディレクトリ名を一覧表示するには?

複数のサブディレクトリとファイルを含むディレクトリがある場合は、正規表現に一致するファイル名(直接または間接)を含むそのディレクトリの直接サブディレクトリ名を一覧X表示したいと思います。X^rf.*\.img$

OS Xでこれを達成するには?

答え1

GNUを使用すると、find各ディレクトリをテストできます。

for i in "$dir"/*/
do
    test -n "$(find "$i" -type f -regex '.*/test[^/]*' -print -quit)" \
       && echo "$i"
done

その後、各ディレクトリはファイルの先頭を検索し、test見つかった場合はそのディレクトリを印刷します。

参考にするいくつかの点があります。

  1. ;で始まるサブディレクトリを無視します。これを考慮する必要がある場合は、Bash FAQを確認して.キャプチャせずに含める方法.を学びます..
  2. 私達はゲームがあればfind早くやめた。-quitこれにより、大規模ファイルシステムツリーで時間が節約されます。
  3. テストは-regex考慮されているフルパス名と一致するため、基本find名にのみ一致する場合は一致時に注意する必要があります/-filename.
  4. -iregex大文字と小文字を区別しない一致には、代替を使用できます-regex
  5. optionsを使用して正規表現構文を選択できます-regextype

質問の特定のパターンにワイルドカードを使用できるため、次のようになります。

for i in "$dir"/*/
do
    test -n "$(find "$i" -type f -name 'rf*.img' -print -quit)" && echo "$i"
done

答え2

zshすでにそこにいると仮定X):

typeset -U subdirs
subdirs=(*/**/rf*.img(.e_'REPLY=${REPLY%%/*}'_))
print -rl -- "${subdirs[@]}"

これは 、すべて*/**/rf*.imgのサブディレクトリ内のすべてのファイルrf*.img、glob修飾子をglob.e、通常のファイルのみを選択し、それぞれが一意の要素を持つ配列として定義された配列(重複なし)にパスの最初のコンポーネントのみを保存します。次に、配列の各要素を印刷します。

答え3

以下を使用してリストを取得できます。findそしてパイプを通してgrep:

(cd X && find . -type d -maxdepth 1 | sed -e 's,^./,,' | grep -E '^rf.*\.img$' )

私は内部に名前を取得するためにサブシェルを使用しましたX。それ以外の場合は、パスを考慮する必要がありますfind

繰り返しサブディレクトリが必要な場合は、この-maxdepth 1オプションを省略できます。しかし、これは正規表現を調整する必要があることを意味します。

(cd X && find . -type d | sed -e 's,^./,,' | grep -E '^(.*/)?rf.*\.img$' )

この場合、sedコマンドは重複しますが無害です。

答え4

使用しperlgrepそのglob

#!/usr/bin/env perl
use strict;
use warnings;

my @file_list = grep { /^rf.*\.img$/ } glob "*";
print join ( "\n", @file_list );

または1行で:

perl -e 'print join ( "\n", grep { /^rf.*\.img$/ } glob "*" )'

注 -globシェルスタイルのワイルドカード拡張を実行するので、glob "*/*/name/*"同様にすることができます。任意の再帰深度が必要な場合は、次のものを使用できますFile::Find

#!/usr/bin/env perl
use strict;
use warnings;

use File::Find;

sub print_match {
    #Default match is against $_ which is filename. 
    #can match $File::Find::name for full name.
    #or $File::Find::dir
    print if  /^rf.*\.img$/;
}

find ( \&print_match, "/path/to/search" );

もう一度文で言うと:

perl -MFile::Find -e 'find ( sub { print if  /^rf.*\.img$/ }, "/my/path/to/search" );'

関連情報