bash - 在 n 次匹配后可靠地停止 bash 查找
问题描述
我正在尝试找到一种可靠的方法来在例如 10 次匹配之后停止/终止查找操作。下面的代码说明了一个不优雅的例子。
find . -type f -iname "*.txt" -exec myscript.sh \{\} \;
其中 myscript.sh 当前仅输出匹配文件的名称
我已经尝试了一些在这里找到的建议,例如管道进入 head -n 10 或管道进入 grep -m 10 。但这些并不能可靠地阻止查找。刷新事物之前的 Stdbuf 同样无济于事。
有可靠的方法吗?
我试过这些但没有成功:
find . -type f -iname "*.txt" -exec myscript.sh \{\} \; | head -n 10
find . -type f -iname "*.txt" -exec myscript.sh \{\} \; | head -n 10 && tail -f /var/log/kern.log & read -t 10 ;kill $!
find . -type f -iname "*.txt" -exec myscript.sh \{\} \; | grep -m .
解决方案
您不能阻止您的find
命令在终止之前生成超过 10 个匹配项。shell并行运行,并且find
可以在 shell 终止管道之前轻松地在其输出缓冲区中排队十多行输出。head
find
您可以做的是重构管道,以防止它出现任何症状。例如,
find . -type f -iname "*.txt" -print0 |
head -z -n 10 |
xargs -r0 myscript.sh
这依赖于几个 GNU 扩展(即,打印以空字符结尾的文件名的选项,以及对应的-print0
选项和同上),所以它不是可移植的,但如果你安装它,它应该可以在大多数 Linux 发行版以及其他地方工作标准实用程序的 GNU 版本(可能随后称为、等)。find
-z
head
-0
xargs
gfind
ghead
gxargs
空终止对鲁棒性很重要;如果您的文件名包含换行符head
等。可以在中间切掉文件名,当然,xargs
不知道某些换行符是文件名的一部分,而不是参数分隔符。即使您目前没有任何名称包含换行符的文件名,您也希望针对任何不是一次性的解决方案来防止这种情况 - 稍后当您遇到带有换行符的文件名时解决问题将是繁琐而复杂。
或者,重构-exec
:
find . -type f -iname "*.txt" -exec sh -c '
for arg in $(seq 10); do
myscript.sh "$1"
shift
done
exit 222' _ {} +
exit 222
应该导致find
在第一次-exec
调用后失败而中止。+
after-exec
使得find
尽可能多的参数传入,类似于xargs
. (如果文件名真的很长,和/或你的系统ARG_MAX
真的很小,这可能会在第一次调用中接收不到十个文件,但我认为这种极端情况是病态的。)
推荐阅读
- npm - 当一个使用纱线和另一个 npm 时,如何在两个存储库之间链接?
- javascript - Reactjs,从兄弟更新所有子组件
- php - 将用逗号分隔的文本拆分为一个数组,但忽略转义分隔符 \,
- python - 将 Python 函数从外部传递给另一个函数
- node.js - express 区分动态段和其他静态段
- jquery - 如何使用 jquery.scrollTo 和 jquery(.load) 方法,在同一个 div 中加载外部页面
- json - “jq.”打印的值与 json 文件中存在的值不同
- go - 如何为以文件路径作为参数的golang方法提供windows完整路径
- c# - 我可以用我的 C# 代码做些什么来将它应用到我在 Unity 中的 UI?
- java - 如何清除片段回栈?