我正在尝试编写一个脚本,它将递归地为目录中的每个文件应用 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