Read line by line from Bash standard input

I am learning language and the track says the following about it:

It should read one input (from standard input) at a time (each record is a line and then ends with a new line).

My questions are two:

  • How to read line by line from standard input in Bash? So far I have used the "read string" , but I do not think it reads the line at a time.

  • I do not know if this is a stupid question, but as soon as I created the script, how can I provide more lines for the input of the script (read, of course, from standard input). For example, from insert two lines ( hello and world ). How to pass bash script these two lines?

+5
source share
2 answers

1) How to read line by line from standard input in Bash? So far I have used the "read string", but I do not think it reads the line at a time.

The prototype for read is:

 read [options] name[s ...] 

read will read a line input in name name1 name2 ... , dividing the line based on the contents of the Internal Field Separator ( IFS ). The default value for IFS is ' \t\n' (i.e. space tab newline ). If you specify only one variable in read , you will see the entire line in this variable (unless you set a new delimiter with the -d option to read ). If you provide more than one variable (for example, read -r name name1 ), the word will be split based on the current IFS value. Value if you provide the string hello world :

 read -r name 

name="hello world" . On the other hand, if you provide the same line:

 read -r name name1 

name="hello" , name1="world" . What if there are extra words in the line, but only two variables? Let's say now your line is "hello big wide world" , which happens to:

 read -r name name1 

name="hello" , name1="big wide world" . The words in string assigned to your variables in order, and if there are not enough variables to store each word in a string, the last variable will contain all the remaining words in the string that was not previously assigned.

You change how word breaks occur by changing IFS . Take a close look at the answer provided by Anubhava for an example. You can specify any character to whom you would like to separate the words. (useful, for example, parsing a csv file to set IFS=$',\n' and words divided by ',' instead of space)

To make sure you read the whole line in a variable, you can specify only one variable in read and set IFS='$\n' to ensure word separation only on newline . ( Note: providing change as part of the while restricts the IFS change in the scope of this loop. For example:

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

It will ensure that each line on stdin is read in line , while maintaining the normal separation of words outside the loop. Inside the loop, you can add each row to the array, as anubhava shows in his answer. (to keep all spaces IFS= )

+8
source

You can do something like this:

 # 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 
+4
source

All Articles