2012-08-10 36 views

Trả lời

21

Hãy xem xét những điều sau nhiều dòng biến

x=$(echo -e "a\nb\nc d e") 

và một quá trình đơn giản cho mỗi dòng: chỉ echo nó với một prefix = LINE: và với dấu nháy đơn xung quanh dòng. Một trong các mã sau đây sẽ làm hài lòng yêu cầu rằng:

while read line; do echo "LINE: '${line}'"; done <<< "$x" 

hoặc

while read line; do echo "LINE: '${line}'"; done < <(echo "$x") 

Không tạo ra một subshell (để bạn có thể, ví dụ, thiết lập các biến trong vòng lặp và truy cập chúng bên ngoài của nó), và cả hai đầu ra

LINE: 'a' 
LINE: 'b' 
LINE: 'c d e' 

Nhưng giả sử thay vào đó bạn có

x=$(echo -e "a \n b\nc d e") 
# note--------^--^ 

và vấn đề khoảng trắng ở đầu và cuối cho ứng dụng của bạn (ví dụ: phân tích cú pháp sứ Git). Cả hai mã trên sẽ cung cấp cho chính xác cùng một đầu ra cho các biến sau/dữ liệu như cho các cựu, mà không phải là những gì bạn muốn. Để giữ khoảng trắng ở đầu và cuối, thay thế while read line bằng while IFS= read -r line. Ví dụ, một trong các mã sau

while IFS= read -r line; do echo "LINE: '${line}'"; done <<< "$x" 

hoặc

while IFS= read -r line; do echo "LINE: '${line}'"; done < <(echo "$x") 

sẽ sản xuất

LINE: 'a ' 
LINE: ' b' 
LINE: 'c d e' 

Xem Greg Wooledge's excellent Bash FAQ để biết chi tiết.

+0

đây là giải pháp hoàn hảo, chỉ tò mò thôi, tại sao không chỉ x = "a \ nb \ nc d e"? –

+0

@ SenthilKumar, chuỗi đó chứa 10 charactes: 'a', '\', 'n', 'b', v.v ... "\ n" không phải là dấu ngoặc kép đặc biệt bên trong. Trong bash, người ta có thể viết '$" một \ nb \ nc d e "' để có các dòng mới thực được nhúng trong chuỗi. Cờ "-e" cho 'echo' xử lý" \ n "làm dòng mới chứ không phải hai ký tự indvidual. – chepner

+0

@chepner: thx, '$' là mới đối với tôi, nhưng nó hoạt động với dấu nháy đơn '$' một \ nb \ nc d e'' –

1

Mặc dù tôi thường sử dụng "khi đọc" để xử lý các biến nhiều dòng, gần đây tôi đã có một trường hợp nó xóa không gian hàng đầu khỏi mỗi dòng trong một tệp. Sử dụng này thay vì cố định vấn đề của tôi:

printf %s "$var" | while IFS= read -r line 
do 
    echo "$line" 
done 

Mã lấy từ this Unix Stack Exchange answer.

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