Первый цикл имеет for TOUPLE in $NUMBERS
со значением по умолчанию $IFS
- числа разделены пробелами.Внутри цикла вы меняете $IFS
, и это изменение является постоянным.Это влияет не только на следующий set -- $TOUPLE
, но и на остальную часть сценария.
Когда второй for TRIPLE in $NUMBERS
выполняет изменение на $IFS
, удерживает $NUMBERS
от правильного разбиения.Он разделен запятыми вместо пробелов.Упс.
Если вы хотите изолировать циклы друг от друга, самый простой способ убедиться, что это заключить их в скобки, чтобы они выполнялись в подоболочках.Переменные в подоболочках не влияют на родительскую оболочку.
(
for TOUPLE in $NUMBERS; do
IFS=','
set -- $TOUPLE
echo "($1, $2, $3)"
done
)
echo
(
for TRIPLE in $NUMBERS; do
IFS=','
set -- $TRIPLE
echo "($1, $2, $3)"
done
)
Если вы переключите set
на read
, вы можете временно изменить $IFS
на время действия read
с и избежатьэтот беспорядок целиком.
for TUPLE in $NUMBERS; do
IFS=',' read a b c <<< "$TUPLE"
echo "($a, $b, $c)"
done
Я бы пошел дальше и вообще не стал бы зацикливаться на строковой переменной.Массив лучше подходит и не требует разделения строк.Это хорошая привычка держаться подальше от не цитируемых переменных расширений.
tuples=(1,2,3 4,5,6 7,8,9)
for tuple in "${tuples[@]}"; do
IFS=',' read a b c <<< "$tuple"
echo "($a, $b, $c)"
done