Следующий скрипт создает ожидаемый вывод с пробелом:
Скрипт
for i in {1..100}; do
IFS= read c
printf %s "$c$i"
done < <(yes $' A\nB\nC\n\D')
Вывод
A1B2C3D4 A5B6C7D8 A9B10C11D12 A13B14C15D16 A17B18C19D20 A21B22C23D24 A25B26C27D28 A29B30C31D32 A33B34C35D36 A37B38C39D40 A41B42C43D44 A45B46C47D48 A49B50C51D52 A53B54C55D56 A57B58C59D60 A61B62C63D64 A65B66C67D68 A69B70C71D72 A73B74C75D76 A77B78C79D80 A81B82C83D84 A85B86C87D88 A89B90C91D92 A93B94C95D96 A97B98C99D100
Пояснение
Чтобы прочитать последовательность 1 2 3 ... 100
во всю ее длину, нам нужно повторять последовательность A B C D
снова и снова.yes
- это команда, которая повторяет свой аргумент до бесконечности.yes x
печатает
x
x
x
...
Чтобы позволить yes
печатать что-то другое в каждой строке, мы используем хитрость.$' A\nB\nC\nD'
- это строка, содержащая разрывы строк ($''
- это так называемая цитата bash ansi-c).yes $' A\nB\nC\nD'
напечатает
A
B
C
D
A
B
...
Вместо того, чтобы печатать на консоль, мы хотим использовать текст позже.Для этого мы могли бы написать yes ... | someCommand
или someCommand < <(yes ...)
, что имеет некоторые преимущества перед конвейером.Последний называется процесс замещения .Обратите внимание, что for ...; done
- это всего лишь одна команда.Перенаправленный stdin может быть прочитан из любой точки цикла for
.