使用使用通配符的函数中的路径

使用使用通配符的函数中的路径

众所周知,解析 ls 的输出是一般来说是个坏主意一种解决方案是使用 globbing 而不是 ls 来“安全”地循环目录中的文件。

for path in /path/to/search/*; do
    ...
    # Do more filtering
    ...
    echo "$path"
done

该函数会进一步过滤glob匹配的一些结果,并输出剩余的路径。

但是,如果我想在其他地方重用这个逻辑,我可以通过函数安全地使用它的输出并循环它吗?

function myglob() {
    for path in /path/to/search/*; do
        ...
        # Do more filtering
        ...
        echo "$path"
    done
}

function myExample() {
    results=$(myglob)
    for i in "$results"; do
        echo "$i"
    done
}

或者我必须始终复制全局逻辑并对内部逻辑进行较小的更改?

答案1

不,您不能重复使用您所显示的循环输出,因为它完全复制了问题ls,并且增加了echo可能解释文件名中的反斜杠的问题。

相反,如果您使用具有数组和名称引用的 shell 语言(如bash4.3+ 中),则可以稍微不同地执行此操作:

myglob () {
   declare -n list="$1"

   list=( /path/to/search/* )
}

myexample () {
    local results=()
    myglob results

    for pathname in "${results[@]}"; do
        printf '%s\n' "$pathname"
    done

    # or shorter, just
    # printf '%s\n' "${results[@]}"
}

这里,该myglob函数采用 中变量的名称list,这是一个名称引用变量。这意味着任何使用list实际上都会使用命名变量。该函数只是扩展 glob 并将结果存储在其中,list就好像它是一个数组一样。

然后该myexample函数myglob使用字符串进行调用results。因此, listin 中的变量将myglob引用该results变量,并将扩展模式存储在其中。

然后该函数继续用作results项目数组。

如果myglob需要做过滤:

myglob () {
    declare -n list="$1"

    list=()
    for pathname in /path/to/search/*; do
        # decide whether to use "$pathname" or not
        # then, if it is to be used,
        list+=( "$pathname" )
    done
}

也就是说,如果要将项目返回给调用者,则循环扩展模式并将项目附加到列表中。

相关内容