从标准输入Bash逐行读取

时间:2015-07-04 07:57:49

标签: bash unix stdin

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

  

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

我的问题是两个:

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

  2. 我不知道这是不是一个愚蠢的问题,但是一旦创建了脚本,我怎么能把更多的行作为输入提供给脚本(当然从标准输入中读取)。例如,从我插入两行(worldif (move_uploaded_file($this->request->data['News']['image_url']['tmp_name'], WWW_ROOT. 'media/' . date('Y-m-d'). $this->request->data['News']['image_url']['name'])) { $this->request->data['News']['image_url'] = date('Y-m-d') . $this->request->data['News']['image_url']['name']; } $this->Modelname->save($this->request->data['News']); )。我如何向bash脚本提供这两行?

2 个答案:

答案 0 :(得分:12)

  
      
  1. 如何从Bash中的标准输入逐行阅读?直到现在我   用过"读取字符串"但我不认为它一次只读一行。
  2.   

read的原型是:

read [options] name[s ...]

read会根据内部字段分隔符line)的内容,将name name1 name2 ...的输入读入IFS分割行。 IFS的默认值为' \t\n'(即space tab newline)。如果您只向read提供单个变量,则会将整行读入该变量(除非您使用-d选项设置了新的分隔符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来更改分词的方式。仔细看看anubhava提供的答案。您可以自由指定要分割的单词。 (有助于解析csv文件以设置IFS=$',\n'并将单词拆分为','而不是空格

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

while IFS='$\n' read -r line; do
    # do whatever with line
done

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

答案 1 :(得分:4)

您可以这样做:

# 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