Читать построчно со стандартного ввода Баш
Я учусь Баш язык и экзамен трек говорит так:
Он должен читать один вход (от стандартного входа) за раз (каждая запись является строкой, а затем заканчивается новой строкой).
мои вопросы два:
как читать строку за строкой из стандартного ввода в Bash? До сих пор я использовал
"read string"
но я не думаю, что он читает строку за раз.Я не знаю, если это глупый вопрос, но после создания скрипта, как я могу дать больше строк скрипту в качестве ввода (чтение из стандартного ввода, конечно). Например,stdin вставить две строки (
hello
иworld
). Как я могу дать скрипт эти две линии?
2 ответов
1) Как читать строку за строкой из стандартного ввода в Bash? До сих пор я используется "читать строку", но я не думаю, что она читает строку за раз.
прототип read
- это:
read [options] name[s ...]
read
прочитал line
вход в name name1 name2 ...
разделение строки на основе содержимого Разделитель Внутреннего Поля (IFS
). Значение по умолчанию для IFS
is ' \t\n'
(то есть space
tab
newline
). Если вы предоставьте только одну переменную read
, вы прочитаете всю строку в этой переменной (если вы не установили новый разделитель с до read
). Если вы предоставляете более одной переменной (например,read -r name name1
) разбиение будет происходить на основе текущего значения IFS
. Значение, если вы предоставляете строку hello world
в:
read -r name
name="hello world"
. С другой стороны, если вы предоставите ту же строку:
read -r name name1
name="hello"
, name1="world"
. Что, если ты ... есть лишние слова в строке, но только 2 переменные? Скажите, что ваша строка теперь "hello big wide world"
, что случается с:
read -r name name1
name="hello"
, name1="big wide world"
. Слова в string
назначаются вашим переменным по порядку, и если переменных недостаточно для хранения каждого слова в строке, последняя переменная будет содержать все оставшиеся слова в строке, ранее не назначенной.
вы изменяете, как происходит разделение слов, изменяя IFS
. Внимательно посмотреть на ответ Анубхава, например. Вы можете указать любой символ, на который вы хотите разделить слова. (полезно сказать разбор установить IFS=$',\n'
и разделите слова на ','
вместо пробела)
чтобы убедиться, что Вы читаете всю строку в переменную, вы можете предоставить только одну переменную read
и set IFS='$\n'
для обеспечения разделения слов происходит только на newline
. (Примечание: предоставление изменения в составе while
петля ограничивает IFS
изменение объема этого цикла. Например:
while IFS='$\n' read -r line; do
# do whatever with line
done
будет гарантировать, что каждая линия на stdin
будет читаться в line
при сохранении нормального разделения слов вне цикла. Внутри цикла вы можете добавить каждую строку в массив, как показывает Анубхава в своем ответе. (чтобы сохранить все пробелы IFS=
используется)
вы можете сделать что-то вроде этого:
# array to hold all lines read
lines=()
# read all lines in lines array
while IFS= read -r line; do
lines+=( "$line" )
done < file
# read 3 more lines from stdin
for ((i=0; i<3; i++)); do
read -rp "Enter a line: " line
lines+=( "$line" )
done