从标准输入Bash逐行读取

mar*_*zzu 8 unix bash stdin

我正在学习语言,考试曲目说:

它应该一次读取一个输入(来自标准输入)(每个条目是一个字符串,然后以换行符结束).

我的问题是两个:

  1. 如何从Bash中的标准输入逐行阅读?直到现在我用过,"read string"但我不认为它一次读取一行.

  2. 我不知道这是不是一个愚蠢的问题,但是一旦创建了脚本,我怎么能将更多行作为输入提供给脚本(当然从标准输入中读取).例如,从我插入两行(helloworld).我如何给bash脚本这两行?

Dav*_*ica 13

  1. 如何从Bash中的标准输入逐行阅读?到目前为止,我使用"读取字符串",但我不认为它一次读取一行.

原型read是:

read [options] name[s ...]
Run Code Online (Sandbox Code Playgroud)

read将根据内部字段分隔符()的内容读取line输入以name name1 name2 ...分割行.是(即)的默认值.如果只提供单个变量,则会将整行读入该变量(除非您使用选项设置了新的分隔符).如果您提供多个变量,(例如)将根据当前值进行单词拆分.这意味着如果您提供字符串:IFSIFS' \t\n'space tab newlineread-dreadread -r name name1IFShello world

read -r name
Run Code Online (Sandbox Code Playgroud)

name="hello world".另一方面,如果您提供相同的字符串:

read -r name name1
Run Code Online (Sandbox Code Playgroud)

name="hello",name1="world".如果你的行中有多余的单词但只有2个变量怎么办?现在说你的字符串"hello big wide world",会发生什么:

read -r name name1
Run Code Online (Sandbox Code Playgroud)

name="hello",name1="big wide world".string按顺序将单词分配给变量,如果变量不足以保存字符串中的每个单词,则最后一个变量将包含先前未分配的字符串中的所有剩余单词.

您可以通过更改来更改分词的方式IFS.仔细看看anubhava提供的答案.您可以自由指定要分割的单词.(有助于解析csv文件设置IFS=$',\n'并将单词拆分','而不是空格)

为确保将整行读入变量,您只能提供单个变量read并设置IFS='$\n'为确保仅在单词上进行分词newline.(注意:将更改作为while循环的一部分进行限制会限制对该循环范围的IFS更改.例如:

while IFS='$\n' read -r line; do
    # do whatever with line
done
Run Code Online (Sandbox Code Playgroud)

将确保stdin读取每一行,line同时保留循环外的正常分词.在循环内部,您可以将每行添加到数组中,因为anubhava在他的答案中显示.(用于保留所有空格IFS=)


anu*_*ava 5

你可以这样做:

# 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
Run Code Online (Sandbox Code Playgroud)