如何从路径获取目录名

如何从路径获取目录名

我有这个:

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

三种方式:

首先,你的xargs方法失败了,因为你dirname一次给出了多个路径名。相反,将路径名一一传递给它:

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

with-print0findwith-0xargs路径名作为空分隔列表而不是换行分隔列表传递。-r的选项将xargs确保dirname在没有来自 的输入时不会运行find

如果您知道您的文件名不包含嵌入的换行符:

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

其次,调用一个内联 shell 脚本,该脚本在文件上一一find运行: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)要求之前的通配模式仅扩展到常规文件 ( .),如果没有与该模式匹配的文件则扩展为空(N,如nullglobbash,并且还包含隐藏名称(D,如dotglobbash。最后: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

相关内容