8

一連のディレクトリの名前を DIR から DIR.OLD に変更したいと考えています。理想的には、次を使用します。

find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print0 | xargs -0 -r -I file mv file file.old

しかし、これを実行したいマシンには BusyBox がインストールされており、BusyBox xargs は「-I」オプションをサポートしていません。

ファイルの配列を収集し、シェルスクリプトでそれらを実行するための一般的な代替方法は何ですか?

4

3 に答える 3

12

コマンドの機能を使用できるため-exec、パイプはまったく必要ありません。{}find

find -maxdepth 1 -type d -name "*.y" -mtime +`expr 2 \* 365` -exec mv "{}" "{}.old" \;

また、「.」を指定する必要はありません。パス - これは のデフォルトです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

コマンドを実行するたびに追加の /bin/sh を呼び出す(実際にfindは実行する)ためだと思いますが、シェルループはそうではありません。xargsexec(3)while

Upd:あなたの busybox バージョンがコマンド-execのオプションサポートなしでコンパイルされた場合、他の回答 ( onetwo ) で提案されているループまたはがあなたのやり方です。findwhilexargs

于 2012-01-06T14:40:37.890 に答える
3
  1. forループを使用します。残念ながら、busybox も理解していないと思うread -0ので、改行を適切に処理することはできません。必要がない場合は、次のようにするのが最も簡単です。

    find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print | while read file; do mv -- "$file" "$file".old; done
    
  2. コマンドとしてa を使用しsh -cます。最初の引数に名前を付けるための少し奇妙な の使用$0(通常はスクリプト名であり、 で$0スクリプトを抑制している間-c、引数は引き続き に移動します$0) と、-n 1バッチ処理を回避するための の使用に注意してください。

    find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print0 | xargs -0 -r -n 1 sh -c 'mv -- "$0" "$0".old'
    

編集 おっと:私は再びについて忘れていましfind -execた。

于 2012-01-06T14:38:12.563 に答える
1

別の方法は、ループを使用することです。

find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print | while IFS= read file
do
    mv "$file" "$file".old
done
于 2012-01-06T14:35:51.253 に答える