ディレクトリと同じ名前のファイルを検索する

ディレクトリと同じ名前のファイルを検索する

次の問題があります:

ディレクトリには、、およびのExample13 つのファイルがあります。Example1ThingsPictures

ディレクトリには、、およびのExample23 つのファイルがあります。Example2Example3Pictures

ディレクトリ名に一致するファイルのみを表示するリストが必要です。これは、Example1およびですExample2。diff、find、locate、ls などを試しましたが、何も達成できませんでした。

答え1

バックリファレンスを使用した正規表現で、格納ディレクトリと同じ名前のファイル名を簡単に一致させることができます。これらは、what/ever/something/something2 つのsomething部分が同一でスラッシュを含まない形式のファイル名です。BRE 正規表現構文では、[^/]*スラッシュを含まない任意の文字列と一致し、\(/[^/]*\)スラッシュの後に任意の数のスラッシュ以外の文字が続く文字列と一致し、全体をグループにし、\1最初のグループに一致する同じテキストと一致します。したがって、\(/[^/]*\)\1同じ名前の 2 つのパス セグメントと一致します。.*先頭に追加すると、前のディレクトリ コンポーネントと一致します。

GNU find、FreeBSD find、macOS find など、以下findをサポートするものを使用する場合-regex:

find . -regex '.*\(/[^/]*\)\1'

答え2

通常、ディレクトリの数はファイルよりも少ないため、すべてのディレクトリを検索し、必要なファイル名が含まれているかどうかをテストしてみましょう。

find . -type d -exec sh -c '
    for dirpath do
        filepath="$dirpath/${dirpath##*/}"
        [ -f "$filepath" ] && printf "%s\n" "$filepath"
    done' sh {} +

これにより、ファイルと同じ名前を持つディレクトリにあるすべての通常ファイル (および通常ファイルへのシンボリック リンク) のパス名が出力されます。

テストは、いくつかのディレクトリ パス名を引数として取得する短いインラインsh -cスクリプトで実行されます。各ディレクトリ パス名を反復処理し、探している名前のファイル パス名を構築します。${dirpath##*/}コード内の は に置き換えることができます$(basename "$dirpath")

与えられたディレクトリ構造の例の場合、これは次のように出力されます。

./Example1/Example1
./Example2/Example2

ただテストするだけ任意の名前通常のファイルだけでなく、-fテストをテストに変更します-e

答え3

使用find -exec

find . -type f \
  -exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
  -print

は、内部-printの結果がtrue の場合にのみ実行されます。[ ... ]-exec sh -c '...'

出力:

./Example1/Example1
./Example2/Example2

関連情報