Основная проблема здесь заключается в том, что вторая строка, IFS=, sentences1=($sentences) , устанавливает IFS на «,» навсегда; это означает, что вы получите странное и неожиданное поведение при разборе в оставшейся части скрипта. Обратите внимание, что с чем-то вроде IFS=, read ... этого не произойдет, потому что назначение IFS рассматривается как применение только к команде read ; но в IFS=, sentences1=($sentences) нет реальной команды, только назначения, поэтому назначения обрабатываются как применимые ко всей оболочке.
Итак, давайте посмотрим, что происходит в остальной части сценария. sentences2=$sentences просто копирует sentences в sentences2 , поэтому for sentence in ${sentences2[@]} это немного странно. sentences2 не является массивом (просто строка), поэтому бит [@] ничего не делает, но, поскольку IFS по-прежнему ",", он переводит слово "разбито на слова" в "Hello World" и "Questions" - то есть вы получаете правильный результат, но по неправильной причине.
(Примечание: если бы это был фактический массив, вы бы хотели заключить его в двойные кавычки, как, например, в for sentence in "${sentences2[@]}" чтобы элементы не разделялись на слова.)
Следующая команда for i in $(seq 1 2) - это то, с чего начинается настоящая проблема. seq 1 2 печатает «1 [newline] 2 [newline]», конструкция $( ) обрезает завершающий символ новой строки, а затем «1 [newline] 2» получает разделение слов - но так как там нет запятой, это рассматривается как одно слово (которое содержит новую строку). Таким образом, внутренний цикл выполняется только один раз, с i установленным в «1 [newline] 2».
Следующая строка, echo $i $sentence , печатает «1 [новая строка] 2», затем пробел, за которым следует содержание sentence . На первой итерации с sentence "Hello World" это печатает:
1
2 Hello World
... новая строка в середине делает это похожим на две вещи, которые печатаются, но на самом деле это всего лишь одно echo которое содержит новую строку.
Итак, две большие рекомендации: во-первых, когда вы меняете IFS, измените его позже. Во-вторых, всегда используйте двойные кавычки для ссылок на переменные, чтобы избежать неожиданного разделения слов (и подстановочных знаков). Вот что я получаю за сценарий:
#!/bin/bash
sentences="Hello World,Questions"
saveIFS="$IFS"
IFS=, sentences1=($sentences)
IFS="$saveIFS" # Set IFS back to normal!
for sentence in "${sentences1[@]}"; do # Note double-quotes, and sentences1 is
an actual array
for i in $(seq 1 2); do # No double-quotes, we *want* seq's output to be spli
t
echo "$i" "$sentence" # Double-quotes for safety
done
done