Vòng qua các thư mục con và chạy một lệnh trong mỗi


47

Tôi có một bộ các kho được sắp xếp vào các thư mục dựa trên VCS của chúng (Git, Mercurial, SVN). Với Subversion tôi đã có thể chạy svn update *trong thư mục mẹ và nó sẽ lặp qua từng thư mục và cập nhật từng kho lưu trữ như mong đợi. Đó không phải là trường hợp của Git hoặc Mercurial.

Tôi muốn đưa ra một tập lệnh bash mà tôi có thể chạy để thực hiện chính xác điều đó, lặp qua các thư mục và git pullhoặc hg pulltrong mỗi tập lệnh. Tôi chỉ không có nhiều kinh nghiệm viết kịch bản.


Có thể làm rõ liệu bạn có muốn các lệnh được thực hiện đệ quy (trong tất cả các thư mục con) hay không, trong đó câu trả lời của mj41 là câu duy nhất tôi đã thử (từ đây và tại các trang SO khác) thực hiện điều đó.
r_alex_hall

* thực hiện điều đó với một tinh chỉnh mà tôi đề cập trong một nhận xét về nó.
r_alex_hall

Câu trả lời:


81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done

2
Thnx ... nhưng tôi cũng cần phải nắm bắt lỗi. Làm thế nào tôi có thể làm như vậy. Tôi chưa bao giờ thực hiện lập trình shell trước đây.
shashwat

23

Nếu bạn cần nó được đệ quy:

find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \;

Điều này sẽ đi xuống tất cả các thư mục theo thư mục hiện tại và thực hiện thao tác git trên các thư mục con có thư mục .git (bạn có thể giới hạn nó với -maxdepth).


@thprivileges: thông minh!
Dennis Williamson

9
-execdirở đây tốt hơn nhiều:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann

Đây là một câu trả lời tốt hơn theo ý kiến ​​chủ quan của tôi ... Đã làm việc ngay lập tức cho tôi .. Chúc mừng
Voke Ransom Anighoro

Không giống như câu hỏi liên kết với tôi ở đây, lệnh này thực sự có hiệu quả. Cảm ơn bạn.
dùng1445967

7

Nếu bạn đã cài đặt GNU Parallel http: // www.gnu.org/software/abul/, bạn có thể làm điều này:

cd ~/projects/git/; ls | parallel 'cd {} && git pull'

Điều này sẽ chạy song song vì vậy nếu một số kết nối mạng của máy chủ git bị chậm thì điều này có thể tăng tốc mọi thứ.

Xem video giới thiệu về GNU Parallel để tìm hiểu thêm: http://www.youtube.com/watch?v=OpaiGYxkSuQ


Có thể làm ls */để chắc chắn rằng bạn đang đưa ra đầu vào mạch lạc cd.
Joe Corneli

4

Điều này sẽ làm việc

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;

xóa -maxdepth 1cờ, đây là lệnh duy nhất tôi tìm thấy trong rất nhiều lần tìm kiếm và thử thực thi lệnh một cách đệ quy (trong tất cả các thư mục con, không chỉ các thư mục giảm một cấp).
r_alex_hall

0

Để làm nó đệ quy mà không sử dụng findnhưngforloop

for dir in ~/projects/git/*/*/; do (cd "$dir" && git pull); done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.