Tôi đang tìm vòng lặp cơ bản như:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
nhưng để bash.
Tôi đang tìm vòng lặp cơ bản như:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
nhưng để bash.
Câu trả lời:
Từ trang web này :
for i in $(seq 1 10);
do
echo $i
done
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
ArrayLength=${#array[@]}
thế nào để chúng ta sử dụng nó ở đây thay vì max
?
Bash for
bao gồm một biến (trình lặp) và danh sách các từ mà trình lặp sẽ lặp lại.
Vì vậy, nếu bạn có một danh sách các từ hạn chế, chỉ cần đặt chúng theo cú pháp sau:
for w in word1 word2 word3
do
doSomething($w)
done
Có thể bạn muốn lặp lại một số số, vì vậy bạn có thể sử dụng seq
lệnh để tạo danh sách các số cho mình: (từ 1 đến 100 chẳng hạn)
seq 1 100
và sử dụng nó trong vòng lặp FOR:
for n in $(seq 1 100)
do
doSomething($n)
done
Lưu ý $(...)
cú pháp. Đó là một hành vi bash, nó cho phép bạn vượt qua các đầu ra từ một lệnh (trong trường hợp của chúng tôi từ seq
) khác (các for
)
Điều này thực sự hữu ích khi bạn phải lặp lại tất cả các thư mục trong một số đường dẫn, ví dụ:
for d in $(find $somepath -type d)
do
doSomething($d)
done
Khả năng tạo danh sách là vô hạn.
Bash 3.0+ có thể sử dụng cú pháp này:
for i in {1..10} ; do ... ; done
.. mà tránh tạo ra một chương trình bên ngoài để mở rộng chuỗi (chẳng hạn như seq 1 10
).
Tất nhiên, điều này có cùng một vấn đề với for(())
giải pháp, bị ràng buộc với bash và thậm chí là một phiên bản cụ thể (nếu điều này quan trọng với bạn).
Hãy thử bash
trợ giúp tích hợp:
$ help for
for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
#! /bin/bash
function do_something {
echo value=${1}
}
MAX=4
for (( i=0; i<MAX; i++ )) ; {
do_something ${i}
}
Dưới đây là một ví dụ cũng có thể hoạt động trong các trình bao cũ hơn, trong khi vẫn hiệu quả với số lượng lớn:
Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'
Nhưng chúc may mắn khi làm được những điều hữu ích bên trong awk
: Làm cách nào để sử dụng các biến shell trong tập lệnh awk?
do
/ điển hình done
.
Tôi thường thích sử dụng một biến thể nhỏ trên tiêu chuẩn cho vòng lặp. Tôi thường sử dụng điều này để chạy một lệnh trên một loạt các máy chủ từ xa. Tôi tận dụng khả năng mở rộng dấu ngoặc nhọn của bash để tạo các vòng lặp for cho phép tôi tạo các vòng lặp for không phải số.
Thí dụ:
Tôi muốn chạy lệnh thời gian hoạt động trên máy chủ giao diện người dùng 1-5 và máy chủ phụ trợ 1-3:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
Tôi thường chạy lệnh này dưới dạng lệnh một dòng với dấu chấm phẩy ở cuối các dòng thay vì phiên bản dễ đọc hơn ở trên. Cân nhắc sử dụng chính là dấu ngoặc nhọn cho phép bạn chỉ định nhiều giá trị được chèn vào một chuỗi (ví dụ: kết quả đăng trước {foo, bar} trong prefoopost, prebarpost) và cho phép đếm / chuỗi bằng cách sử dụng dấu chấm kép (bạn có thể sử dụng a. .z, v.v.). Tuy nhiên, cú pháp dấu chấm kép là một tính năng mới của bash 3.0; các phiên bản trước sẽ không hỗ trợ điều này.
nếu bạn chỉ quan tâm đến giải pháp "for ((...))" được trình bày ở trên là tốt nhất, nhưng nếu bạn muốn thứ gì đó tuân thủ POSIX SH sẽ hoạt động trên tất cả các liên kết, bạn sẽ phải sử dụng "expr" và "while" và đó là bởi vì "(())" hoặc "seq" hoặc "i = i + 1" không di động giữa các shell khác nhau
Tôi luôn sử dụng các biến thể này để xử lý tệp ...
cho các tệp trong * .log; làm echo "Thực hiện công việc với: $ files"; echo "Làm nhiều thứ hơn với: $ files"; làm xong;
Nếu việc xử lý danh sách tệp là điều bạn quan tâm, hãy xem xét tùy chọn -execdir cho tệp .