bash loop thông qua danh sách các chuỗi


13

Có thể định dạng mẫu này:

for i in string1 string2 stringN
do
 echo $i
done

với một cái gì đó tương tự như thế này:

for i in 
string1
string2
stringN
do
 echo $i
done

EDIT: Xin lỗi vì sự nhầm lẫn, đã không nhận ra rằng có các phương pháp thực thi tập lệnh khác nhau - sh <scriptname>so với bash <scriptname>và cũng là điều mà tôi không thể đặt tên ngay bây giờ - #!/bin/sh#!/bin/bash:)


Vấn đề bạn đang cố gắng giải quyết là gì?
jesse_b

Bạn đã thử những gì bạn yêu cầu để xem liệu nó có hoạt động không?
DopeGhoti

@Jesse_b khả năng đọc và khả năng quản lý của chuỗi các chuỗi

@DopeGhoti vâng tôi đã làm

@waayee: Trong trường hợp đó, một mảng là đặt cược tốt nhất của bạn. Xem câu trả lời của Glenn Jackman.
jesse_b

Câu trả lời:


32

Sử dụng mảng trong bash có thể hỗ trợ khả năng đọc: cú pháp mảng này cho phép khoảng trắng tùy ý giữa các từ.

strings=(
    string1
    string2
    "string with spaces"
    stringN
)
for i in "${strings[@]}"; do
    echo "$i"
done

1
Điều này có vẻ thanh lịch nhất, nhưng không may mắc lỗi: Lỗi cú pháp: "(" không mong muốn

1
@waayee, sau đó bạn không chạy nó trong Bash. Hãy nhớ rằng đó shkhông nhất thiết là Bash và đặc biệt là không có trên Debian và Ubuntu.
ilkkachu

1
@ilkkachu Hãy nghĩ rằng tôi hiểu ngay bây giờ - phải chạy "bash <scriptname>" chứ không phải "sh <scriptname>" :)

@waayee, hoặc đặt một dòng hashbang / shebang thích hợp và chạy nó như một tệp thực thi. Yêu cầu đọc: Liệu shebang xác định shell chạy script?
ilkkachu

1
@rrrrr, câu hỏi của bạn có lẽ đã trả lời ở đây: stackoverflow.com/q/12314451/7552
glenn jackman

4

Bạn có thể thoát khỏi dấu ngắt dòng bằng dấu gạch chéo ngược:

$ for i in \
> hello \
> world
> do
> echo $i
> done
hello
world
$

2

Bạn có thể thoát các dòng mới trước / sau mỗi mục mà bạn lặp lại:

for i in \
    string1 \
    string2 \
    stringN
do
   printf '%s\n' "$i"
done

Hoặc, cho ví dụ đơn giản này:

printf '%s\n' string1 string2 stringN

trong đó có kết quả tương tự.

Liên quan:

Biến thể sử dụng một bashmảng:

strings=(
    string1
    string2
    stringN
)

printf '%s\n' "${strings[@]}"

1

Nếu chuyển sang zshlà một tùy chọn:

for string (
  string1
  'other string'
  etc..
) printf '%s\n' "$string"

0

Bạn có thể sử dụng looplệnh, có sẵn ở đây , như vậy:

$ loop "echo $ITEM" --for string1,string2,string3

hoặc, nếu bạn có một danh sách dưới dạng tệp:

$ cat file_list.txt | loop "echo $ITEM"

0
list='a b c d'
for element in $list;do 
    echo "$element"
done

Bạn đang thiếu dấu chấm phẩy!
41754

Lưu ý rằng điều này sẽ hoạt động miễn là mỗi chuỗi là một từ riêng biệt. Ngay khi bạn có khoảng trắng trong chuỗi của mình, khoảng trắng sẽ chia chuỗi thành nhiều từ. Ngoài ra, nếu $listchuỗi chứa các ký tự tên tập tin ( list='* * * *'), shell sẽ có khả năng thay thế các tên này bằng tên tệp phù hợp.
Kusalananda

0

Điều tương tự, ít văn bản:

array=(
        string{1..7}
)

for i in "${array[@]}"; do
    echo "$i"
done

string1v.v. không phải là các giá trị theo nghĩa đen sẽ được hiển thị, chúng là các phần giữ chỗ, vì vậy phương pháp này không hiệu quả.
Stephen Kitt

Nếu vậy, tại sao phải bận tâm array ( … )? chỉ cần làm for i in string{1..7}; do echo "$i"; done; thậm chíprintf '%s\n' string{1..7}
αғsнιη
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.