我正在尝试编写一个脚本来将我手动运行的两个单独的命令统一到一个 bash 脚本中,然后我可以执行 cron。
第一个命令是对具有特定名称和大小的文件进行简单查找
find /some/path -type f -name file.pl -size +10M
这将生成几个匹配的文件及其完整路径。然后,我手动将这些路径复制到 for 循环中,作为下一个脚本的参数。
for path in /some/path/1/file.pl /some/path/2/file.pl /some/path/3/file.pl ; do perl /my/script.pl $path ; done
看起来应该很容易将其放入单个 shell 脚本中,但发现它很困难。
答案1
这就是-exec
谓词的用途:
find /some/path -type f -name file.pl -size +10M -exec perl /my/script.pl {} \;
如果你确实想拥有你的外壳根据 的输出运行命令,那么如果您想可靠,则find
该命令必须是bash
/特定的,如下所示:zsh
zsh
:IFS=$'\0' for f ($(find /some/path -type f -name file.pl -size +10M -print0)) { /my/script.pl $f }
尽管在 中
zsh
,您可以简单地执行以下操作:for f (./**/file.pl(.LM+10)) /my/script.pl $f
bash
/zsh
while IFS= read -rd '' -u3 file; do /my/script.pl "$file" done 3< <(find /some/path -type f -name file.pl -size +10M -print0)
bash
无论您在POSIX shell 或其他 POSIX shell中做什么,请避免:
for file in $(find...)
或者至少通过将字段分隔符固定为换行符并禁用通配符来减轻问题:
IFS='
'; set -f; for file in $(find...)
(对于包含换行符的文件路径,这仍然会失败)。
答案2
如果您使用 GNU 工具,以下内容也应该有效:
find /some/path -type f -name file.pl -size +10M -print0 | xargs -0 -n 1 -r perl /my/script.pl
解释:
- 该选项
-print0
使 GNU find 用字节分隔文件名\0
。由于\0
字节不能是文件名的一部分,因此这唯一地分隔文件名。 - 该选项
-0
告诉 GNU xargs 将标准输入读取为\0
- 分隔的文件名列表。 - 该选项
-n 1
强制不超过一个文件名传递给您的脚本(如果您的脚本可以处理完整的文件列表作为参数,则忽略它)。 - 最后,
-r
是另一个 GNU 扩展,如果没有提供文件名,它会阻止您的程序运行。
答案3
这应该可以做到
for path in `find /some/path -type f -name file.pl -size +10M`; do perl /my/script.pl $path ;done