2012-01-06 36 views
7

Tôi muốn đổi tên một loạt các thư mục từ DIR sang DIR.OLD. Lý tưởng nhất là tôi sẽ sử dụng như sau:Các giải pháp thay thế cho xargs -l

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

Nhưng máy tôi muốn thực hiện điều này trên có BusyBox cài đặt và xargs BusyBox không hỗ trợ tùy chọn "-I".

Một số phương pháp thay thế phổ biến để thu thập một mảng tệp là gì và sau đó thực thi chúng trong tập lệnh trình bao?

+2

\ "about? Điều đó sẽ cho biết tìm các tệp danh sách được gọi chính xác' "* .y" '(dấu ngoặc kép sẽ được chuyển để tìm và trong khi dấu * sẽ được mở rộng bằng trình bao, nó sẽ không tìm thấy gì và thông qua thông qua anyway), mà tôi nghi ngờ tồn tại. –

+0

Trong số các tùy chọn biên dịch khác nhau cho busybox là 'CONFIG_FEATURE_FIND_PRINT0',' CONFIG_FEATURE_FIND_EXEC', 'CONFIG_FEATURE_FIND_EXEC_PLUS' - cách tiếp cận sẽ hoặc sẽ không hoạt động tùy thuộc vào chi tiết chính xác cách * bản sao của bạn được biên dịch. –

Trả lời

9

Bạn có thể sử dụng -exec{} tính năng của lệnh find do đó bạn không cần bất kỳ ống tại tất cả: ''

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

Ngoài ra bạn không cần phải xác định đường dẫn - điều này là mặc định cho find. Và bạn đã sử dụng dấu gạch chéo thêm trong "*.y". Tất nhiên nếu tên tập tin của bạn không thực sự chứa dấu ngoặc kép.

Trong sự công bằng cần lưu ý, phiên bản đó với vòng lặp while read là nhanh nhất được đề xuất tại đây. Dưới đây là một số đo Ví dụ:

$ 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 

Tôi nghĩ rằng đó là vì findxargs gọi thêm/bin/sh (trên thực tế exec(3) hiện nó) mỗi khi cho thực thi một lệnh, trong khi vỏ while vòng lặp thì không.

UPD: Nếu phiên bản busybox của bạn đã được biên soạn mà không -exec tùy chọn hỗ trợ cho các find lệnh thì while vòng lặp hoặc xargs, đề xuất trong các câu trả lời khác (one, two), là con đường của bạn.

+0

+1: Lệnh find đi kèm với tùy chọn '-exec'. Đó là một chút chậm hơn so với 'xargs' bởi vì nó thực hiện lệnh cho mỗi và mọi tập tin được tìm thấy. Nhưng, nó hoạt động, và nó không có các vấn đề _whitespace_ vì shell không liên quan. Nếu bạn không thể sử dụng 'xargs' vì các vấn đề khoảng trắng, hãy sử dụng' -exec'. Các vòng lặp không hiệu quả như tham số '-exec' vì chúng thực hiện một lần cho mỗi và mọi tệp, nhưng có các vấn đề khoảng trắng mà' xargs' có. –

+1

'xargs' cũng thực hiện lệnh cho mỗi tệp trong trường hợp này để' tìm' không chậm hơn. –

+0

Bạn nói đúng. Tôi không nhìn vào lệnh. Thông thường, bạn sử dụng xargs thay vì '-exec' vì xargs kết hợp nhiều tệp như nó có thể trên dòng lệnh và thực hiện lệnh chỉ một vài lần. –

1

Một cách khác là sử dụng một vòng lặp:

find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print | while IFS= read file 
do 
    mv "$file" "$file".old 
done 
+1

'read' sử dụng dòng mới làm dấu phân cách. Hoặc bạn cần 'đọc -0' (nhưng tôi không chắc nó được thực hiện trong busybox) hay bạn chỉ cần' -print'. –

+0

đã đồng ý. Tôi đã cập nhật câu trả lời của mình. – dogbane

2
  1. Sử dụng một vòng lặp for. Thật không may, tôi không nghĩ rằng busybox cũng hiểu được read -0, vì vậy bạn sẽ không thể xử lý các dòng mới một cách chính xác. Nếu bạn không cần, chỉ cần đơn giản nhất là:

    find . -maxdepth 1 -type d -name \"*.y\" -mtime +`expr 2 \* 365` -print | while read file; do mv -- "$file" "$file".old; done 
    
  2. Sử dụng sh -c làm lệnh. Lưu ý việc sử dụng hơi lạ của $0 để đặt tên cho đối số đầu tiên (thường là tên tập lệnh và chuyển đến $0 và trong khi bạn đang tắt tập lệnh với -c, đối số vẫn chuyển đến $0) và sử dụng -n 1 để tránh việc thực hiện mẻ.

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

SửaOops: Tôi quên về find -exec một lần nữa.

+0

Busybox thậm chí không hiểu print0. Nhưng vòng lặp whie của bạn hoạt động –

Các vấn đề liên quan