次の質問があります。
ディレクトリには、およびExample1
の3つのファイルが含まれています。Example1
Things
Pictures
ディレクトリには、およびExample2
の3つのファイルが含まれています。Example2
Example3
Pictures
ディレクトリ名と一致するファイルのみを表示するリストが必要です。これはExample1
とですExample2
。私はdiff、find、Locate、lsを試しましたが、どこにも到達できませんでした。
答え1
逆参照を使用すると、含まれているディレクトリと同じ名前のファイル名を正規表現で簡単に一致させることができます。これはスラッシュのない同じファイル名のwhat/ever/something/something
2つの部分です。something
BRE正規表現構文では、[^/]*
スラッシュを含まない文字列を一致させ、\(/[^/]*\)
スラッシュの後に非スラッシュ文字が続くすべての文字列を一致させ、全体をグループ化し、最初のグループと\1
同じテキストを一致させるので、\(/[^/]*\)\1
2つに一致します。同じ名前のパスセグメント。.*
以前のディレクトリコンポーネントと一致するように最初に追加されました。
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