递归地将 bash 函数应用于子文件夹中的每个文件

递归地将 bash 函数应用于子文件夹中的每个文件

我正在尝试编写一个脚本,它将递归地为目录中的每个文件应用 bash 函数。例如,如果该目录tests中有我的所有文件和子目录,则脚本

find tests -type f -print0 | xargs -0 echo

工作完美。现在我希望能够应用 bash 函数而不仅仅是 echo,所以我想出了这样的方法:

function fun() {
    echo $1
}

export -f fun

find tests -type f -print0 | xargs -0 bash -c 'fun "$@"'

然而,这仅在测试中输出单个文件,而之前它输出所有文件。我希望这两个运行相同,不是吗?

答案1

使用 shell 脚本。

引用自这个优秀的答案

除了 shell 之外,其他程序是否需要能够使用它?如果是这样,它必须是一个脚本。

正如其他答案中已经指出的,可能是可能的通过导出函数来解决这个问题,但这肯定是一个很多使用脚本更简单。

#!/bin/bash
# I'm a script named "fun"!  :)
printf '%s\n' "$@"

然后你只需将fun脚本放在 PATH 中的某个位置(可能在~/bin),确保它是可执行的,然后你就可以运行:

find tests -type f -exec fun {} +

答案2

-n1有两种方法可以解决此问题:您可以告诉 xargs 使用或循环函数内的所有参数一次仅使用一个参数运行命令fun

function fun() { echo $1 }
export -f fun
find tests -type f -print0 | xargs -n1 -0 bash -c 'fun "$@"' --

或者

function fun() { while [ -n "$1" ]; do echo $1; shift; done }
export -f fun
find tests -type f -print0 | xargs -0 bash -c 'fun "$@"' --

答案3

如果您使用 GNU Parallel,它看起来像这样:

function fun() {
    echo "$@"
}
export -f fun

find tests -type f -print0 | parallel -0 -Xj1 fun

相关内容