Bash 模式匹配除目录之外的所有文件

Bash 模式匹配除目录之外的所有文件

在 bash 中,如何指定匹配当前目录中除子目录之外的所有内容的模式。鉴于该模式*/匹配所有子目录,我尝试了(打开 extglob):

$ echo !(*/)

但这没有用。

答案1

find . -maxdepth 1 ! -type d

细节:

  • -maxdepth 1将搜索限制为当前目录

  • ! -type d消除目录

答案2

匹配目录的原因*/是最终/限制匹配目录。仅当 位于模式后面时才会触发此效果/,您不能/在 中使用括号内!(*/)。 bash 中没有内置功能来执行您想要的操作。

您可以对所有文件进行循环并构建一个数组。

non_directories=()
for x in *; do
  [ -d "$x" ] || non_directories+=("$x")
done
somecommand "${non_directories[@]}"

find如果您想对所有文件执行命令,也可以使用, 。如果您的 find 实现支持它(GNU、BSD、BusyBox),请使用-mindepth-maxdepth来仅列出当前目录中的条目(带有./前缀)。用于! -name '.*'省略点文件(如果您确实想省略它们)。

find . -mindepth 1 -maxdepth 1 ! -type d -exec somecommand {} +

如果您只能假设 POSIX find,请使用-prune以避免递归。

find . -name . -o -type d -prune -o -exec somecommand {} +

如果要将 的输出填充find到数组变量中,请注意解析 的输出find需要对文件名进行额外的假设。你最好用一个循环。

在 zsh 中,您可以使用全局限定符: *(^/),或*(.)仅匹配常规文件。

答案3

有点啰嗦,但是:

for f in *; do if [ ! -d "$f" ]; then echo "$f"; fi; done

-d是一个文件测试操作符检查参数是否是目录。

上式还可以简化为

for f in *; do [ ! -d "$f" ] && echo "$f"; done

答案4

我不确定您想要实现两个选项中的哪一个 - 基于文件系统属性排除的 bash globing,还是仅显示目录中文件的方法?

如果是第一个,我不确定这是否可能。全局只是扩展,文件名是任何目录的基础 - bash 本身不区分文件名或目录名。

如果第二个 - 你已经得到了 2 个答案,另一个使用 ls:

ls -dF * | grep -v "/$"  

相关内容