====== BASH - Files - Read a file - Read fields from a file ======
To read fields within each line of the file, additional variables may be used with the read:
----
===== Fields are separated with white-space (space or tab characters only) =====
If an input file has 3 columns separated by white-space (space or tab characters only).
while read -r first_name last_name phone; do
# Only print the last name (second column).
printf '%s\n' "$last_name"
done < "$file"
----
===== Fields are NOT separated with white-space =====
If the field delimiters are not whitespace, set the IFS (internal field separator):
# Extract the username and its shell from /etc/passwd:
while IFS=: read -r user pass uid gid gecos home shell; do
printf '%s: %s\n' "$user" "$shell"
done < /etc/passwd
**NOTE:** IFS is set to a colon, **:**, as every field in the passwd file is separated by a colon.
----
===== Tab-delimited files =====
**NOTE:** For tab-delimited files, use **IFS=$'\t'**.
**WARNING:** Multiple tab characters in the input will be considered as one delimiter (and the **IFS=$'\t\t'** workaround does not work in Bash).
----
===== Not knowing how many fields a line contains =====
You do not necessarily need to know how many fields each line of input contains.
* If you supply more variables than there are fields, the extra variables will be empty.
* If you supply fewer, the last variable gets "all the rest" of the fields after the preceding ones are satisfied.
For example:
read -r first last junk <<< 'Bob Smith 123 Main Street Saint Helier Jersey'
**NOTE:**
* **first**: will contain "Bob"
* **last**: will contain "Smith".
* **junk**: holds everything else.
----
===== Throwaway variable =====
read -r _ _ first middle last _ <<< "$record"
**NOTE:** The throwaway variable **_** can be used as a "junk variable" to ignore fields.
* It, and any other variable, can be used more than once in a single read command, if we don't care what goes into it.
* The first two fields are skipped.
* The next three fields are reading into variables.
* The final **_** will absorb any remaining fields on the line.
* It does not need to be repeated there.
**WARNING:** This usage of **_** is only guaranteed to work in Bash.
* Many other shells use **_** for other purposes that will at best cause this to not have the desired effect, and can break the script entirely.
* It is better to choose a unique variable that isn't used elsewhere in the script, even though **_** is a common Bash convention.
----