使用通配符搜索匹配的文件,而无需在 Bash 脚本中使用 find

使用通配符搜索匹配的文件,而无需在 Bash 脚本中使用 find

对于作业,我应该编写一个 bash 脚本,它可以充当非常基本的 bash 脚本find,但无需实际使用该find命令。例如,如果我输入以下内容:

my_find ~/homedir/ -name 'test*' -name '*.o' -type f

我需要它来搜索与通配符名称~/homedir/匹配的任何内容,然后在这些结果中搜索与名称匹配的任何内容,最后(尽管可能是多余的)仅搜索文件。最后,它会列出所有结果。test*AND*.o

到目前为止,我已经创建了一个存储目录路径(dirpath=$1)的变量。然后我用shift它来摆脱第一个参数,然后执行此操作(请注意,-type尚未实现):

while (($#)); do
    if [[ $1 == "-name" ]]; then
        # process the name here?
        shift 2 # get rid of -name "name"
    fi
done

我有点想知道如何构建甚至做到这一点。我有一个部分完成的函数,它将通过目录路径递归,但我不确定如何/在哪里处理传入的参数。这是查看每个目录的递归函数。

recurse_path () {
    for i in "$@"; do
        # process and store matching file names in the array?
        if [[ -d "${i}" ]]; then
            cd "${i}"
            recurse_path *
        fi
    done
}

那么,在使用此函数时,如何搜索匹配的文件名并将结果存储在数组中呢?另外,这是执行此操作的正确方法,还是有可能更简单的方法来更新我在查看每个命令时获得的结果?我是 bash 脚本的新手,所以我将不胜感激任何建议。

答案1

让我尝试点一些基本的东西。

1.

如果我们已经可以遍历目录树,下一步就是在当前访问的目录中进行搜索。这取决于我们想要支持什么风格的模式语法。正则表达式是完全不同的事情。也许我们对 shell 内置的模式语法感到满意。那么这样就可以了。

for i in * ; do for p in <patterns> ; do
        if [[ $i == $p ]]
        ...
        fi
done ; done

2.

为了解析命令行,bash有内置的getopts,请参阅手册。

3.

对于数组,请参阅手册。

答案2

一个肮脏的解决方案看起来像:

boolRememberNext=0
rememberString=""

for arg in $*; do
   if [ ${boolRememberNext} -eq 1 ]; then
      rememberString="${rememberString} ${arg}"
   fi
   if [ "${arg}" = "-name" ]; then
      boolRememberNext=1
   else
      boolRememberNext=0
   fi
done

echo ${rememberString} | while read filemask; do
   unquotedFile=$(echo "$filemask" | tr -d "'")
   ls -R1 ~/homedir/ | grep ":" | cut -d: -f1 | while read dir; do
      ls ${dir}/unquotedFile
   done
done

为什么会脏呢?

  • 很多循环,文件系统被访问很多次
  • 忽略不正确的命令行语法
  • 目录和文件名中不能有 :
  • 用 tr 取消对 var 的引用将无法处理 * 组合
    我不想为此使用 eval

可以采取哪些措施来改进解决方案?

您可以将中间结果存储在本地变量中,改进特殊字符的处理并检查语法。

您还可以执行 als ~/homedir/*并向搜索路径添加星号,直到找不到文件。通过一些过滤器解析所有文件(awk?)。检查您找到的文件,它们是文件,而不是目录。

相关内容