Skip to content

Read a file (data stream, variable) line-by-line (and/or field-by-field)?

Terminal window
while IFS= read -r line; do
echo "$line"
done <file

If file may not include a newline at the end, then:

Terminal window
while IFS= read -r line || [ -n "$line" ]; do
echo "$line"
done <file

Looping through the output of a command field by field

Section titled “Looping through the output of a command field by field”

Let’s assume that the field separator is :

Terminal window
while IFS= read -d : -r field || [ -n "$field" ];do
echo "**$field**"
done < <(ping google.com)

Or with a pipe:

Terminal window
ping google.com | while IFS= read -d : -r field || [ -n "$field" ];do
echo "**$field**"
done
Terminal window
readarray -t arr <file

Or with a loop:

Terminal window
arr=()
while IFS= read -r line; do
arr+=("$line")
done <file
Terminal window
var='line 1
line 2
line3'
readarray -t arr <<< "$var"

or with a loop:

Terminal window
arr=()
while IFS= read -r line; do
arr+=("$line")
done <<< "$var"
Terminal window
var='line 1
line 2
line3'
while IFS= read -r line; do
echo "-$line-"
done <<< "$var"

or

Terminal window
readarray -t arr <<< "$var"
for i in "${arr[@]}";do
echo "-$i-"
done

Looping through the output of a command line by line

Section titled “Looping through the output of a command line by line”
Terminal window
while IFS= read -r line;do
echo "**$line**"
done < <(ping google.com)

or with a pipe:

Terminal window
ping google.com |
while IFS= read -r line;do
echo "**$line**"
done

Let’s assume that the field separator is : (colon) in the file file.

Terminal window
while IFS= read -d : -r field || [ -n "$field" ]; do
echo "$field"
done <file

For a content:

Terminal window
first : se
con
d:
Thi rd:
Fourth

The output is:

Terminal window
**first **
** se
con
d**
**
Thi rd**
**
Fourth
**

Let’s assume that the field separator is :

Terminal window
var='line: 1
line: 2
line3'
while IFS= read -d : -r field || [ -n "$field" ]; do
echo "-$field-"
done <<< "$var"

Output:

Terminal window
-line-
- 1
line-
- 2
line3
-

Let’s assume that the field separator is :

Terminal window
arr=()
while IFS= read -d : -r field || [ -n "$field" ]; do
arr+=("$field")
done <file

Let’s assume that the field separator is :

Terminal window
var='1:2:3:4:
newline'
arr=()
while IFS= read -d : -r field || [ -n "$field" ]; do
arr+=("$field")
done <<< "$var"
echo "${arr[4]}"

Output:

Terminal window
newline

Reads file (/etc/passwd) line by line and field by field

Section titled “Reads file (/etc/passwd) line by line and field by field”
#!/bin/bash
FILENAME="/etc/passwd"
while IFS=: read -r username password userid groupid comment homedir cmdshell
do
echo "$username, $userid, $comment $homedir"
done < $FILENAME

In unix password file, user information is stored line by line, each line consisting of information for a user separated by colon (:) character. In this example while reading the file line by line, the line is also split into fields using colon character as delimiter which is indicated by the value given for IFS.

Sample input

Terminal window
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin

Sample Output

Terminal window
mysql, 27, MySQL Server /var/lib/mysql
pulse, 497, PulseAudio System Daemon /var/run/pulse
sshd, 74, Privilege-separated SSH /var/empty/sshd
tomcat, 91, Apache Tomcat /usr/share/tomcat6
webalizer, 67, Webalizer /var/www/usage

To read line by line and have the entire line assigned to variable, following is a modified version of the example. Note that we have only one variable by name line mentioned here.

#!/bin/bash
FILENAME="/etc/passwd"
while IFS= read -r line
do
echo "$line"
done < $FILENAME

Sample Input

Terminal window
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin

Sample Output

Terminal window
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin
ParameterDetails
IFSInternal field separator
fileA file name/path
-rPrevents backslash interpretation when used with read
-tRemoves a trailing newline from each line read by readarray
-d DELIMContinue until the first character of DELIM is read (with read), rather than newline