eat*_*oaf 8 bash shell find xargs busybox
我想将一堆dirs从DIR重命名为DIR.OLD.理想情况下,我会使用以下内容:
find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print0 | xargs -0 -r -I file mv file file.old
Run Code Online (Sandbox Code Playgroud)
但我要执行此操作的机器已安装BusyBox,而BusyBox xargs不支持"-I"选项.
有哪些常用的替代方法可以收集文件数组,然后在shell脚本中执行它们?
pra*_*oid 11
您可以使用-exec
与{}
该功能find
命令,所以你并不需要在所有的任何管道:
find -maxdepth 1 -type d -name "*.y" -mtime +`expr 2 \* 365` -exec mv "{}" "{}.old" \;
Run Code Online (Sandbox Code Playgroud)
您也不需要指定'.' 路径 - 这是默认值find
.而且你使用了额外的斜杠"*.y"
.当然,如果您的文件名实际上不包含引号.
公平地说,应该注意,带while read
循环的版本是这里提出的最快版本.以下是一些示例测量:
$ cat measure
#!/bin/sh
case $2 in
1) find "$1" -print0 | xargs -0 -I file echo mv file file.old ;;
2) find "$1" -exec echo mv '{}' '{}.old' \; ;;
3) find "$1" | while read file; do
echo mv "$file" "$file.old"
done;;
esac
$ time ./measure android-ndk-r5c 1 | wc
6225 18675 955493
real 0m6.585s
user 0m18.933s
sys 0m4.476s
$ time ./measure android-ndk-r5c 2 | wc
6225 18675 955493
real 0m6.877s
user 0m18.517s
sys 0m4.788s
$ time ./measure android-ndk-r5c 3 | wc
6225 18675 955493
real 0m0.262s
user 0m0.088s
sys 0m0.236s
Run Code Online (Sandbox Code Playgroud)
我认为这是因为find
并且每次执行命令时xargs
调用额外的/ bin/sh(实际上都是exec(3)
这样),而shell while
循环则不会.
更新:如果您的busybox版本是在没有-exec
选项支持的情况下编译的,find
那么while
循环或xargs
在其他答案(一,二)中建议的是您的方式.