временное изменение IFS перед циклом for [дубликат]
Я знаю, что SHELL
позволяет присваивать переменные непосредственно перед командой, так что IFS=":" read a b c d <<< "$here_string"
работает ...
Мне было интересно, не работают ли такие назначения, когда они выполняются с помощью составных операторов, таких как циклы? Я пробовал что-то вроде, IFS=":" for i in $PATH; do echo $i; done
но это привело к синтаксической ошибке. Я всегда мог сделать что-то подобное oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS"
, но я хотел знать, есть ли способ заставить такие встроенные назначения работать для составных операторов, таких как for
циклы?
Ответы
for
является зарезервированным словом и поэтому следует особым правилам :
Следующие слова признаются зарезервированными:
! {} case do done elif else esac fi for if in then до while
Это распознавание должно происходить только тогда, когда ни один из символов не цитируется и когда слово используется как:
Первое слово команды
Первое слово, следующее за одним из зарезервированных слов, кроме case , for или in
Третье слово в команде случае (только в действительно в данном случае)
Третье слово в команде for ( в этом случае допустимы только in и do )
Если вы пытаетесь
IFS=":" for i in $PATH; do echo $i; done
по приведенным выше правилам это не for
цикл, так как ключевое слово не является первым словом команды. Но ваше намерение может быть достигнуто с помощью
IFS=: printf '%s\n' $PATH
$PATH
подвергается разделению слов, :
как ожидалось, и каждое полученное слово печатается с printf
последующим переводом строки.
Возможно, вы знакомы с этим подходом:
while IFS= read -r line; do
while
это первое слово команды, и IFS
присвоение применяется к read
, так что все в порядке.