thay đổi IFS tạm thời trước vòng lặp for [trùng lặp]
Tôi biết rằng SHELL
phép gán biến diễn ra ngay lập tức trước một lệnh, như vậy sẽ IFS=":" read a b c d <<< "$here_string"
hoạt động ...
Điều tôi tự hỏi là liệu các phép gán như vậy không hoạt động khi được thực hiện với các câu lệnh ghép như vòng lặp? Tôi đã thử một cái gì đó như thế IFS=":" for i in $PATH; do echo $i; done
nhưng nó dẫn đến lỗi cú pháp. Tôi luôn có thể làm điều gì đó như thế oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS"
, nhưng tôi muốn biết liệu có cách nào tôi có thể làm cho các phép gán nội tuyến như vậy hoạt động cho các câu lệnh ghép như for
vòng lặp không?
Trả lời
for
là một từ dành riêng và như vậy tuân theo các quy tắc đặc biệt :
Các từ sau đây sẽ được coi là từ dành riêng:
! {} case do done elif else esac fi cho if in then cho đến khi
Việc nhận dạng này chỉ xảy ra khi không có ký tự nào được trích dẫn và khi từ được sử dụng như:
Từ đầu tiên của một lệnh
Từ đầu tiên sau một trong những từ dành riêng khác hơn là trường hợp , cho , hoặc trong
Từ thứ ba trong lệnh trường hợp (chỉ trong mới hợp lệ trong trường hợp này)
Từ thứ ba trong lệnh for (chỉ trong và do hợp lệ trong trường hợp này)
Nếu bạn cố gắng
IFS=":" for i in $PATH; do echo $i; done
, theo các quy tắc trên, đó không phải là một for
vòng lặp, vì từ khóa không phải là từ đầu tiên của lệnh. Nhưng mục đích của bạn có thể đạt được với
IFS=: printf '%s\n' $PATH
$PATH
trải qua quá trình tách từ :
như mong đợi và mỗi từ kết quả được in ra printf
, theo sau là một dòng mới.
Bạn có thể quen với cách tiếp cận hợp lệ này:
while IFS= read -r line; do
while
là từ đầu tiên của lệnh và việc IFS
gán áp dụng cho read
, vì vậy tất cả đều OK.