Làm thế nào để một iterate đúng trên dòng trong bash hoặc trong một biến, hoặc từ đầu ra của một lệnh? Chỉ cần đặt biến IFS thành một dòng mới hoạt động cho đầu ra của một lệnh nhưng không phải khi xử lý một biến chứa các dòng mới.
Ví dụ
#!/bin/bash
list="One\ntwo\nthree\nfour"
#Print the list with echo
echo -e "echo: \n$list"
#Set the field separator to new line
IFS=$'\n'
#Try to iterate over each line
echo "For loop:"
for item in $list
do
echo "Item: $item"
done
#Output the variable to a file
echo -e $list > list.txt
#Try to iterate over each line from the cat command
echo "For loop over command output:"
for item in `cat list.txt`
do
echo "Item: $item"
done
Điều này cho đầu ra:
echo:
One
two
three
four
For loop:
Item: One\ntwo\nthree\nfour
For loop over command output:
Item: One
Item: two
Item: three
Item: four
Như bạn có thể thấy, lặp lại biến hoặc lặp qua cat
lệnh in từng dòng một một cách chính xác. Tuy nhiên, đầu tiên cho vòng lặp in tất cả các mục trên một dòng. Bất kỳ ý tưởng?
Với bash, nếu bạn muốn nhúng dòng mới vào một chuỗi, hãy kèm theo chuỗi $''
:
$ list="One\ntwo\nthree\nfour"
$ echo "$list"
One\ntwo\nthree\nfour
$ list=$'One\ntwo\nthree\nfour'
$ echo "$list"
One
two
three
four
Và nếu bạn có một chuỗi như vậy đã có trong một biến, bạn có thể đọc nó theo từng dòng với:
while read -r line; do
echo "... $line ..."
done <<< "$list"
Bạn có thể dùng while
+ read
:
some_command | while read line ; do
echo === $line ===
done
Btw. các -e
tùy chọn để echo
không chuẩn. Sử dụng printf
thay vào đó, nếu bạn muốn tính di động.
#!/bin/sh
items="
one two three four
hello world
this should work just fine
"
IFS='
'
count=0
for item in $items
do
count=$((count+1))
echo $count $item
done
Đây là một cách thú vị để thực hiện vòng lặp for:
for item in ${list//\\n/
}
do
echo "Item: $item"
done
Một chút hợp lý hơn / có thể đọc được sẽ là:
cr='
'
for item in ${list//\\n/$cr}
do
echo "Item: $item"
done
Nhưng đó là tất cả quá phức tạp, bạn chỉ cần một không gian trong đó:
for item in ${list//\\n/ }
do
echo "Item: $item"
done
Bạn $line
biến không chứa dòng mới. Nó chứa các phiên bản của \
theo dõi bởi
n
. Bạn có thể thấy điều đó rõ ràng với:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo $list | hexdump -C
$ ./t.sh
00000000 4f 6e 65 5c 6e 74 77 6f 5c 6e 74 68 72 65 65 5c |One\ntwo\nthree\|
00000010 6e 66 6f 75 72 0a |nfour.|
00000016
Sự thay thế là thay thế những người có không gian, đủ để nó hoạt động trong các vòng lặp:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\\n/ } | hexdump -C
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
Bản giới thiệu:
$ cat t.sh
#! /bin/bash
list="One\ntwo\nthree\nfour"
echo ${list//\\n/ } | hexdump -C
for item in ${list//\\n/ } ; do
echo $item
done
$ ./t.sh
00000000 4f 6e 65 20 74 77 6f 20 74 68 72 65 65 20 66 6f |One two three fo|
00000010 75 72 0a |ur.|
00000013
One
two
three
four