您将如何列出以以下结尾的文件x、y 或 z在不以以下结尾的子目录中x、y 或 z?
答案1
为了*[xyz]
完全避免下降,并且对于深度为 2 的常规文件(即 find a/x
,但不是ax/x
nora/b
也不是x
,并且不会超出两个目录,如a/b/x
),POSIXly:
LC_ALL=C find . \( ! -name '*[xyz]' -o -prune \) \
-path './*/*' -prune -type f -name '*[xyz]'
这相当于:
printf '%s\n' *[!xzy]/*[xyz]
除此之外,它还会查找隐藏目录和隐藏文件,并且不会查找目录的符号链接,而只会查找常规文件。
如果您想查找*[xyz]
任何深度的常规文件,只要它们直接的父目录不以 GNU 结尾xyz
(因此会找到x
, a/x
, a/b/x
, x/b/x
,但不是x/x
nor a/x/x
)find
:
LC_ALL=C find . -regex '.*[^xyz]/[^/]*[xyz]' -type f
和zsh
:
setopt extended_glob
printf '%s\n' **/*[xzy]~*[xyz]/[^/]#(D.)
POSIXly:
LC_ALL=C find . -name '*[xzy]' -type f -exec sh -c '
for f do
case ${f%/*} in
*[xzy]) ;;
*) printf '%s\n' "$f"
esac
done' sh {} +
如果您根本不想查找内部*[xyz]
,即使在子目录中(也就是说,如果您不想查找x/a/x
),那么那就是:
find . -name '*[xyz]' -prune -type f
-prune
告诉find
不要进入目录(并返回 true)。
或者与zsh
:
setopt extended_glob
printf '%s\n' (*[^xyz]/)#*[xyz](D.)
答案2
1
仅适用于以下位置的文件全部任意深度的子目录:
(继斯蒂芬·查泽拉斯之后)
find . -name '*[xyz]' -prune -type f
2
仅对于深度为 2 的子目录中的文件,请尝试以下操作:
(包括非标准选项。我还不太擅长以不平凡的理解省略它们。有关详细信息,请参阅评论。)
find . -mindepth 2 -maxdepth '2' -wholename "./*[^xyz]/*[xyz]" -type f 2>/dev/null
find
寻找文件
.
告诉 find 从当前目录开始
-mindepth 2
表示搜索应从当前目录深 1 级开始
-maxdepth 2
表示搜索应结束于比当前目录更深的 1 层
-wholename
定义文件路径值./*[^xyz]/*[xyz]
是您在问题中定义的
-type f
告诉 find 仅查找文件
2>/dev/null
告诉 find 不要打印错误消息
3
如果您不仅想要文件还想要目录,这更容易:
ls -d *[^xyz]/*[xyz]
ls
用于列出文件和目录
ls -d
带有不显示目录中内容的ls
选项-d
更新
我只是好奇如何将搜索条件更改为文件名末尾而不是包含文件扩展名。所以搜索会显示文件z.abc 而不是 file.abz
这给出了当前目录中的列表:
ls -d *[xyz].???
在 Linux 中,文件没有您想象的扩展名。扩展名是文件名的一部分。重写之前的所有命令有点复杂,尤其是第一个。
1.
(迄今为止我想到的最好的。)
find . -path '.*[^xyz]/*[xyz].???' -type f | grep -v [xyz]/
2.
find . -mindepth 2 -maxdepth '2' -wholename "./*[^xyz]/*[xyz].???" -type f 2>/dev/null
3.
ls -d *[^xyz]/*[xyz].???