私はこれを持っています:
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-print0
とfind
withは、改行で区切られたリストの代わりに、空で区切られたリストにパス名を-0
渡します。このオプションは、入力なしで実行されないようにします。xargs
-r
xargs
dirname
find
ファイル名に改行文字が含まれていないことがわかっている場合:
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
も含める必要があります。最後に、一致するパス名ごとに「ヘッド」(つまり、ファイル名のないパス名のディレクトリ部分)が返されます。D
dotglob
bash
: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