循环遍历不包括目录的文件

循环遍历不包括目录的文件

我需要我的脚本对当前目录中的每个文件执行某些操作(不包括任何子目录)。

例如,当前路径中有5个文件,但其中1个是文件夹(子目录)。我的脚本应该在运行所述脚本时激活作为参数给出的命令。即“bash script wc -w”应该给出当前目录中每个文件的字数,但不给出任何文件夹的字数,以便输出永远不会有任何“/sub/dir:是一个目录”行。

我当前的脚本:

#!/bin/bash
dir=`pwd`
for file in $dir/*
do
    $* $file
done

我只需要排除循环的目录,但我不知道如何。

答案1

#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

请注意,它还排除符号链接类型的文件以及符号链接解析为目录类型的文件(这可能是您想要的)。

替代方案(来自评论),仅检查文件:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done

答案2

如果您需要做的事情很简单(并且不涉及在主 shell &c 中设置变量),那么可以使用 for 循环的替代方法。

您可以使用findwith-exec和 use-maxdepth 1来避免递归到子目录中。

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

[ -n "$1" ]是为了避免在脚本未传递任何参数时执行目录中的所有文件。

答案3

在 zsh 中,您可以使用全局限定符按文件类型限制通配符匹配。例如,(.)在模式之后添加会将其限制为常规文件。

wc -w *(.)

要处理以-or开头的文件名.,请使用wc -c -- *(.N)or wc -c ./*(.N)。如果您还想包含常规文件的符号链接,请将其设为*(-.).

其他常见的 shell 没有这样的功能,因此您需要使用一些不同的机制来按文件过滤,例如循环测试文件类型或者find

答案4

Bash for 循环排除子目录('/')和链接(@):

for f in `ls|egrep -v '/|@'`; do echo $f; done

相关内容