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

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

次の質問があります。

ディレクトリには、およびExample1の3つのファイルが含まれています。Example1ThingsPictures

ディレクトリには、およびExample2の3つのファイルが含まれています。Example2Example3Pictures

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

答え1

逆参照を使用すると、含まれているディレクトリと同じ名前のファイル名を正規表現で簡単に一致させることができます。これはスラッシュのない同じファイル名のwhat/ever/something/something2つの部分です。somethingBRE正規表現構文では、[^/]*スラッシュを含まない文字列を一致させ、\(/[^/]*\)スラッシュの後に非スラッシュ文字が続くすべての文字列を一致させ、全体をグループ化し、最初のグループと\1同じテキストを一致させるので、\(/[^/]*\)\12つに一致します。同じ名前のパスセグメント。.*以前のディレクトリコンポーネントと一致するように最初に追加されました。

GNU検索、FreeBSD検索、macOS検索、またはその他のサポートされ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

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

出力:

./Example1/Example1
./Example2/Example2

関連情報