2009-08-26 69 views
15

Tôi đang cố gắng recurse thư mục và chạy lệnh trên chúng, sử dụng bash script. Bất kỳ đề xuất?Đệ quy đọc thư mục và thực hiện lệnh trên mỗi thư mục

+3

Vấn đề không rõ ràng. Bạn có đơn giản muốn sử dụng lệnh find để thực hiện một lệnh trên tất cả các tệp bên dưới một thư mục đã cho không? –

+3

câu trả lời nằm trong phiếu bầu của tôi rồi :) – drAlberT

+0

Tôi chỉ muốn đổi tên tất cả các tệp theo thư mục – Jinhua

Trả lời

41

Nếu bạn muốn recurse vào thư mục, thực hiện một lệnh trên mỗi tập tin được tìm thấy trong những người, tôi sẽ sử dụng lệnh find, thay vì viết bất cứ điều gì bằng cách sử dụng shell-script, tôi nghĩ.

Lệnh đó có thể nhận được nhiều tham số, như type để lọc các loại tệp được trả về hoặc exec để thực thi lệnh trên mỗi kết quả.


Ví dụ, để tìm các thư mục đang được một trong những Tôi hiện tại:

find . -type d -exec echo "Hello, '{}'" \; 

Mà sẽ làm cho tôi somehthing như:

Hello, '.' 
Hello, './.libs' 
Hello, './include' 
Hello, './autom4te.cache' 
Hello, './build' 
Hello, './modules' 


Cùng tìm các tệp trong thư mục hiện tại:

find . -type f -exec echo "Hello, '{}'" \; 

mà sẽ làm cho tôi một cái gì đó như thế này:

Hello, './config.guess' 
Hello, './config.sub' 
Hello, './.libs/memcache_session.o' 
Hello, './.libs/memcache_standard_hash.o' 
Hello, './.libs/memcache_consistent_hash.o' 
Hello, './.libs/memcache.so' 
Hello, './.libs/memcache.lai' 
Hello, './.libs/memcache.o' 
Hello, './.libs/memcache_queue.o' 
Hello, './install-sh' 
Hello, './config.h.in' 
Hello, './php_memcache.h' 
... 


Một số sẽ nói "nó không bao" ... Nhưng tại sao lại phát minh ra bánh xe?
(Và, theo một cách, đó là vỏ ^^)


Để biết thêm thông tin, bạn có thể có một cái nhìn tại địa chỉ:

+0

Nếu bạn cần đổi tên thư mục cũng như tệp đệ quy, hãy xem câu trả lời này: http://stackoverflow.com/questions/ 4268591/unix-rename-files-directories-to-upper – JJones

+0

cảm ơn. làm thế nào tôi sẽ điều chỉnh này để tìm chỉ cho các thư mục con của thư mục hiện tại của tôi, và không tìm các thư mục con phụ –

+0

ah. như thế này: 'tìm. -maxdepth 1-dpe d -exec echo "Xin chào, '{}'" \; ' –

1

Hãy xem lệnh find và kiểm tra công tắc -type (sử dụng d để chỉ định thư mục) và -exec (để chỉ định lệnh thực thi).

3

Xin lỗi tôi không hiểu bạn đang hỏi gì. Điều tốt nhất tôi có thể đoán với câu hỏi của bạn là

find -type d -exec scriptname.sh \{\} \; 
+0

Trong trường hợp này, tập lệnh sẽ được thực thi bên trong mỗi thư mục? – Sigur

+1

Không, tập lệnh được thực thi tại vị trí 'tìm'. –

0

Đối với hầu hết các hoạt động tập tin đệ quy, bạn muốn sử dụng find, như câu trả lời khác giải thích.

Có ví dụ về tập lệnh bash đệ quy có trong gói bash-doc. Nếu bạn đã cài đặt các ví dụ đó, nó sẽ là /usr/share/doc/bash/examples/functions/recurse (trên Debian).

7

Something như thế này nên đạt được mục tiêu của bạn:

function RecurseDirs 
{ 
    oldIFS=$IFS 
    IFS=$'\n' 
    for f in "[email protected]" 
    do 
    -----your activity here----- 
     if [[ -d "${f}" ]]; then 
      cd "${f}" 
      RecurseDirs $(ls -1 ".") 
      cd .. 
     fi 
    done 
    IFS=$oldIFS 
} 
+1

[Không phân tích cú pháp 'ls'] (http://mywiki.wooledge.org/ParsingLs), vui lòng! –

3

Một số vỏ cơ bản bỏ lỡ lệnh như 'tìm' và một số các lệnh của họ không hỗ trợ đệ quy. Trong trường hợp đó bạn có thể sử dụng lệnh này để chạy lệnh mong muốn trong tất cả subdirs trong cây:

CDIR=$(pwd) 
for i in $(ls -R | grep :); do 
    DIR=${i%:}     # Strip ':' 
    cd $DIR 
    $1       # Your command 
    cd $CDIR 
done 

Nếu bạn đặt tên cho "recurse.sh" ở trên sau đó sử dụng:

./recurse.sh <command> 

Ví dụ (thay đổi chủ sở hữu/nhóm để 'root' của tất cả các file trong cây):

./recurse.sh "chown 0:0 *" 
+0

[Không phân tích cú pháp 'ls'] (http://mywiki.wooledge.org/ParsingLs), vui lòng! –

6

Bash 4,0 giới thiệu tùy chọn globstar, do đó, một cấu trúc như:

for f in mydir/**/* 
do 
    # operations here 
done 

... sẽ hành động đệ quy trên bất kỳ vùng đất nào bằng $ f. Bật tính năng này bằng "shopt -s globstar", nếu không thì ** sẽ được coi là số ít *.

Tìm thấy đá quý này hôm nay tại http://www.linuxjournal.com/content/globstar-new-bash-globbing-option, sau khi được lấy cảm hứng từ cấu trúc zsh (mà tôi đã bật theo mặc định).

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