#!/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
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
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
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
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
readarray -t arr <file
Or with a loop:
arr=()
while IFS= read -r line; do
arr+=("$line")
done <file
while IFS= read -r line; do
echo "$line"
done <file
If file may not include a newline at the end, then:
while IFS= read -r line || [ -n "$line" ]; do
echo "$line"
done <file
var='line 1
line 2
line3'
readarray -t arr <<< "$var"
or with a loop:
arr=()
while IFS= read -r line; do
arr+=("$line")
done <<< "$var"
var='line 1
line 2
line3'
while IFS= read -r line; do
echo "-$line-"
done <<< "$var"
or
readarray -t arr <<< "$var"
for i in "${arr[@]}";do
echo "-$i-"
done
while IFS= read -r line;do
echo "**$line**"
done < <(ping google.com)
or with a pipe:
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.
while IFS= read -d : -r field || [ -n "$field" ]; do
echo "$field"
done <file
For a content:
first : se
con
d:
Thi rd:
Fourth
The output is:
**first **
** se
con
d**
**
Thi rd**
**
Fourth
**
Let's assume that the field separator is :
var='line: 1
line: 2
line3'
while IFS= read -d : -r field || [ -n "$field" ]; do
echo "-$field-"
done <<< "$var"
Output:
-line-
- 1
line-
- 2
line3
-
Let's assume that the field separator is :
arr=()
while IFS= read -d : -r field || [ -n "$field" ]; do
arr+=("$field")
done <file
Let's assume that the field separator is :
var='1:2:3:4:
newline'
arr=()
while IFS= read -d : -r field || [ -n "$field" ]; do
arr+=("$field")
done <<< "$var"
echo "${arr[4]}"
Output:
newline
Let's assume that the field separator is :
while IFS= read -d : -r field || [ -n "$field" ];do
echo "**$field**"
done < <(ping google.com)
Or with a pipe:
ping google.com | while IFS= read -d : -r field || [ -n "$field" ];do
echo "**$field**"
done
Parameter | Details |
---|---|
IFS | Internal field separator |
file | A file name/path |
-r | Prevents backslash interpretation when used with read |
-t | Removes a trailing newline from each line read by readarray |
-d DELIM | Continue until the first character of DELIM is read (with read ), rather than newline |