xargs -l的替代品

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在其他答案(,)中建议的是您的方式.