パスからディレクトリ名を取得する方法

パスからディレクトリ名を取得する方法

私はこれを持っています:

find . -type f -name '*_test.go' | xargs dirname

しかし、私は次のようになります。

使用法:ディレクトリ名のパス

出力

$ find . -type f -name '*_test.go' 

例:

./pkg_test.go
./v3/organization/organization_test.go
./v3/common/pkg_test.go
./v3/model/boil_main_test.go
./v3/model/boil_queries_test.go
./v3/model/advances_test.go
./v3/model/boil_suites_test.go
./v3/model/psql_main_test.go
./v3/model/psql_suites_test.go

ファイルのディレクトリ名を取得する方法を知っている人はいますか?たぶん絶対パスが必要ですか?

ベストアンサー1

3つの方法:

まず、一度に複数のパス名を指定するxargsため、アプローチは失敗します。dirname代わりに、パス名を1つずつ渡してください。

find . -type f -name '*_test.go' -print0 | xargs -0 -r -I {} dirname {}

with-print0findwithは、改行で区切られたリストの代わりに、空で区切られたリストにパス名を-0渡します。このオプションは、入力なしで実行されないようにします。xargs-rxargsdirnamefind

ファイル名に改行文字が含まれていないことがわかっている場合:

find . -type f -name '*_test.go' | xargs -r -I {} dirname {}

find次に、ファイル内で1つずつ実行されるインラインシェルスクリプトを呼び出します。dirname

find . -type f -name '*_test.go' -exec sh -c '
    for pathname do
        dirname "$pathname"
    done' sh {} +

または、dirname呼び出しの代わりにループでパラメータ置換を使用します(より高速)。

find . -type f -name '*_test.go' -exec sh -c '
    for pathname do
        printf "%s\n" "${pathname%/*}"
    done' sh {} +

第三に、GNUを使用している場合は、find以下を使用してください-printf

find . -type f -name '*_test.go' -printf '%h\n'

最後に、以下を使用する場合zsh

print -rC1 -- ./**/*_test.go(.ND:h)

glob修飾子は、(.ND:h)古いglobbingパターンが通常のファイル()にのみ拡張されている.場合、またはパターンと一致するファイルがない場合は、何も拡張せずに(N、as nullglob)、隠された名前(、as)bashも含める必要があります。最後に、一致するパス名ごとに「ヘッド」(つまり、ファイル名のないパス名のディレクトリ部分)が返されます。Ddotglobbash:h

bash次のようにループで同じことを実行できます。

shopt -s globstar nullglob dotglob

for pathname in ./**/*_test.go; do
    if [[ -f $pathname ]] && [[ ! -h $pathname ]]; then
        printf '%s\n' "${pathname%/*}"
    fi
done

おすすめ記事