Почему следующее ...
c=0; for i in $'1\n2\n3\n4'; do echo iteration $c :$i:; c=$[c+1]; done
распечатать ...
iteration 0 :1 2 3 4:
а не
iteration 0 :1:
iteration 1 :2:
iteration 2 :3:
iteration 3 :4:
Из того, что я понимаю, синтаксис $ 'STRING' должен позволять мне указывать строку с escape-символами. Не следует ли интерпретировать "\ n" как символ новой строки, чтобы цикл for выводился четыре раза, по одному разу для каждой строки? Вместо этого кажется, что символ новой строки интерпретируется как пробел.
Я принял предложение и попытался установить $ IFS. Результаты были одинаковыми.
IFS=$'\n'; c=0; for i in $'1\n2\n3\n4'; do echo iteration $c :$i:; c=$[c+1]; done; unset IFS;
iteration 0 :1 2 3 4:
В своем комментарии Уильям Пурссел говорит, что это не сработало, потому что IFS был переведен на новую строку ... но последующее не сработало.
IFS=' '; c=0; for i in '1 2 3 4'; do echo iteration $c :$i:; c=$[c+1]; done; unset IFS;
iteration 0 :1 2 3 4:
Использование IFS = '' в строке, разделенной символом новой строки, привело к еще большему беспорядку ...
IFS=' '; c=0; for i in $'1\n2\n3\n4'; do echo iteration $c :$i:; c=$[c+1]; done; unset IFS;
iteration 0 :1
2
3
4:
установка IFS на '\ n' вместо $ '\ n' имела тот же эффект, что и IFS = '' ...
IFS='\n'; c=0; for i in $'1\n2\n3\n4'; do echo iteration $c :$i:; c=$[c+1]; done; unset IFS;
iteration 0 :1
2
3
4:
Есть только одна итерация, но по какой-то причине в эхо-строке видна новая строка.
То, что сработало, сначала сохранило строку в переменной, затем зациклило содержимое переменной (без необходимости устанавливать IFS):
c=0; v=$'1\n2\n3\n4'; for i in $v; do echo iteration $c :$i:; c=$[c+1]; done
iteration 0 :1:
iteration 1 :2:
iteration 2 :3:
iteration 3 :4:
Что еще не объясняет, почему существует эта проблема.
Здесь есть шаблон? Является ли это ожидаемым поведением IFS, как определено в ссылке «Размотка»?
разматывать состояния ссылок ... "Оболочка сканирует результаты раскрытия параметров, подстановки команд и арифметического расширения, которые не встречались в двойных кавычках для разделения слов."
Полагаю, это объясняет, почему строковые литералы не разделяются для итерации цикла, независимо от того, какие экранирующие символы используются. Только когда литерал присваивается переменной, эта переменная раскрывается для деления в цикле for. Я думаю, также с подстановкой команд.
Примеры:
Результат подстановки команды делится
c=0; for i in `echo $'1\n2\n3\n4'`; do echo iteration $c :$i:; c=$[c+1]; done
iteration 0 :1:
iteration 1 :2:
iteration 2 :3:
iteration 3 :4:
Часть раскрытой строки разделена, остальные - нет.
c=0; v=$'1 \n\t2\t3 4'; for i in $v$'\n5\n6'; do echo iteration $c :$i:; c=$[c+1]; done
iteration 0 :1:
iteration 1 :2:
iteration 2 :3:
iteration 3 :4 5 6:
Когда раскрытие происходит в двойных кавычках, расщепление не происходит.
c=0; v=$'1\n2\n3 4'; for i in "$v"; do echo iteration $c :$i:; c=$[c+1]; done
iteration 0 :1 2 3 4:
Любая последовательность SPACE, TAB, NEWLINE используется в качестве разделителя для разделения.
c=0; v=$'1 2\t3 \t\n4'; for i in $v; do echo iteration $c :$i:; c=$[c+1]; done
iteration 0 :1:
iteration 1 :2:
iteration 2 :3:
iteration 3 :4:
Я приму ответ отмотки, так как его ссылка дает ответ на мой вопрос.
Не знаю, почему поведение эхо-сигнала в цикле for изменяется со значением IFS.
РЕДАКТИРОВАТЬ: расширен для уточнения.