在linux查找函数,bash - 在Linux中查找-exec shell函数?

bash - 在Linux中查找-exec shell函数?

有没有办法让find执行我在shell中定义的函数? 例如:

dosomething () {

echo "doing something with $1"

}

find . -exec dosomething {} \;

结果是:

find: dosomething: No such file or directory

有没有办法得到find的-exec看到dosomething?

12个解决方案

207 votes

由于只有shell知道如何运行shell函数,因此必须运行shell来运行函数。 您还需要使用export -f标记要导出的函数,否则子shell将不会继承它们:

export -f dosomething

find . -exec bash -c 'dosomething "$0"' {} \;

Adam Rosenfield answered 2019-05-05T18:45:46Z

87 votes

find . | while read file; do dosomething "$file"; done

Jac answered 2019-05-05T18:46:03Z

17 votes

在find中添加引号,如下所示:

export -f dosomething

find . -exec bash -c 'dosomething "{}"' \;

这可以纠正由find返回的特殊字符引起的任何错误,例如,名称中带有括号的文件。

Wagner answered 2019-05-05T18:46:34Z

13 votes

Jak的答案很好,但有一些容易克服的陷阱:

find . -print0 | while IFS= read -r -d '' file; do dosomething "$file"; done

这使用null作为分隔符而不是换行符,因此带有换行符的文件名将起作用。 它还使用-r标志禁用反斜杠转义,没有文件名中的反斜杠将无法正常工作。 它还清除IFS,以便不丢弃名称中潜在的尾随空格。

pajamian answered 2019-05-05T18:47:06Z

8 votes

让脚本调用自己,传递作为参数找到的每个项目:

#!/bin/bash

if [ ! $1 == "" ] ; then

echo "doing something with $1"

exit 0

fi

find . -exec $0 {} \;

exit 0

当您单独运行脚本时,它会找到您要查找的内容并调用自身将每个查找结果作为参数传递。 当脚本使用参数运行时,它会对参数执行命令,然后退出。

Mike Maready answered 2019-05-05T18:47:38Z

6 votes

处理结果大量

为了提高效率,许多人使用$1批量处理结果,但这是非常危险的。 因此,在$0中引入了一种替代方法,可以批量执行结果。

请注意,此方法可能会带有一些警告,例如POSIX-$1中的要求在命令末尾有$0。

export -f dosomething

find . -exec bash -c 'for f; do dosomething "$f"; done' _ {} +

$1将许多结果作为参数传递给单个调用$0,并且find循环遍历这些参数,在每个参数上执行函数dosomething。

上述解决方案在$1开始论证,这就是为什么存在$0(代表find)的原因。

逐个处理结果

以同样的方式,我认为应该纠正被接受的最佳答案

export -f dosomething

find . -exec bash -c 'dosomething "$1"' _ {} \;

这不仅更加明智,因为参数应始终从$1开始,如果find返回的文件名对shell具有特殊含义,则使用$0可能会导致意外行为。

Dominik answered 2019-05-05T18:48:51Z

2 votes

对于那些寻找将在当前目录中的所有文件上执行给定命令的bash函数的人,我已经从上面的答案中编译了一个:

toall(){

find . -type f | while read file; do "$1" "$file"; done

}

请注意,它打破了包含空格的文件名(见下文)。

例如,使用此功能:

world(){

sed -i 's_hello_world_g' "$1"

}

假设我想在当前目录的所有文件中将hello的所有实例更改为world。 我会做:

toall world

为了安全地使用文件名中的任何符号,请使用:

toall(){

find . -type f -print0 | while IFS= read -r -d '' file; do "$1" "$file"; done

}

(但是你需要一个处理-print0的find,例如,GNU find)。

Jason Basanese answered 2019-05-05T18:49:51Z

1 votes

以这种方式执行函数是不可能的。

要解决此问题,您可以将函数放在shell脚本中,并从find调用它

# dosomething.sh

dosomething () {

echo "doing something with $1"

}

dosomething $1

现在用它来查找:

find . -exec dosomething.sh {} \;

codaddict answered 2019-05-05T18:50:31Z

1 votes

将该函数放在一个单独的文件中,并获得find来执行它。

Shell函数是它们定义的shell的内部函数; find将永远无法看到它们。

Angus answered 2019-05-05T18:51:05Z

1 votes

我找到了最简单的方法,在单个do中重复两个命令

func_one () {

echo "first thing with $1"

}

func_two () {

echo "second thing with $1"

}

find . -type f | while read file; do func_one $file; func_two $file; done

edib answered 2019-05-05T18:51:32Z

0 votes

不直接,没有。 查找是在单独的进程中执行,而不是在shell中执行。

创建一个shell脚本,它与您的函数执行相同的工作,并找到可以-exec。

Laurence Gonsalves answered 2019-05-05T18:52:06Z

-4 votes

我会完全避免使用-exec。 为什么不用xargs?

find . -name

Barry answered 2019-05-05T18:52:33Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值