Read a file (data stream, variable) line-by-line (and/or field-by-field)?
Looping through a file line by line
Section titled “Looping through a file line by line”while IFS= read -r line; do echo "$line"done <fileIf file may not include a newline at the end, then:
while IFS= read -r line || [ -n "$line" ]; do echo "$line"done <fileLooping 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 :
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**"doneRead lines of a file into an array
Section titled “Read lines of a file into an array”readarray -t arr <fileOr with a loop:
arr=()while IFS= read -r line; do arr+=("$line")done <fileRead lines of a string into an array
Section titled “Read lines of a string into an array”var='line 1line 2line3'readarray -t arr <<< "$var"or with a loop:
arr=()while IFS= read -r line; do arr+=("$line")done <<< "$var"Looping through a string line by line
Section titled “Looping through a string line by line”var='line 1line 2line3'while IFS= read -r line; do echo "-$line-"done <<< "$var"or
readarray -t arr <<< "$var"for i in "${arr[@]}";do echo "-$i-"doneLooping through the output of a command line by line
Section titled “Looping through the output of a command line by line”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**"doneRead a file field by field
Section titled “Read a file field by field”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 <fileFor a content:
first : second: Thi rd: FourthThe output is:
**first **** second**** Thi rd**** Fourth**Read a string field by field
Section titled “Read a string field by field”Let’s assume that the field separator is :
var='line: 1line: 2line3'while IFS= read -d : -r field || [ -n "$field" ]; do echo "-$field-"done <<< "$var"Output:
-line-- 1line-- 2line3-Read fields of a file into an array
Section titled “Read fields of a file into an array”Let’s assume that the field separator is :
arr=()while IFS= read -d : -r field || [ -n "$field" ]; do arr+=("$field")done <fileRead fields of a string into an array
Section titled “Read fields of a string into an array”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:
newlineReads file (/etc/passwd) line by line and field by field
Section titled “Reads file (/etc/passwd) line by line and field by field”#!/bin/bashFILENAME="/etc/passwd"while IFS=: read -r username password userid groupid comment homedir cmdshelldo echo "$username, $userid, $comment $homedir"done < $FILENAMEIn 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/bashpulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologinsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologintomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologinwebalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologinSample Output
mysql, 27, MySQL Server /var/lib/mysqlpulse, 497, PulseAudio System Daemon /var/run/pulsesshd, 74, Privilege-separated SSH /var/empty/sshdtomcat, 91, Apache Tomcat /usr/share/tomcat6webalizer, 67, Webalizer /var/www/usageTo 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/bashFILENAME="/etc/passwd"while IFS= read -r linedo echo "$line"done < $FILENAMESample Input
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bashpulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologinsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologintomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologinwebalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologinSample Output
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bashpulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologinsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologintomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologinwebalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologinParameters
Section titled “Parameters”| 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 |