Read a file line by line assigning the value to a variable
I have the following .txt file:
Marco Paolo Antonio
I want to read it line-by-line, and for each line I want to assign a .txt line value to a variable. Supposing my variable is
$name, the flow is:
- Read first line from file
- Do some tasks with
- Read second line from file
The following reads a file passed as an argument line by line:
while IFS= read -r line; do echo "Text read from file: $line" done < my_filename.txt
This is the standard form for reading lines from a file in a loop. Explanation:
IFS='') prevents leading/trailing whitespace from being trimmed.
-rprevents backslash escapes from being interpreted.
Or you can put it in a bash file helper script, example contents:
#!/bin/bash while IFS= read -r line; do echo "Text read from file: $line" done < "$1"
If the above is saved to a script with filename
readfile, it can be run as follows:
chmod +x readfile ./readfile filename.txt
If the file isn’t a standard POSIX text file (= not terminated by a newline character), the loop can be modified to handle trailing partial lines:
while IFS= read -r line || [[ -n "$line" ]]; do echo "Text read from file: $line" done < "$1"
|| [[ -n $line ]] prevents the last line from being ignored if it doesn't end with a
read returns a non-zero exit code when it encounters EOF).
If the commands inside the loop also read from standard input, the file descriptor used by
read can be chanced to something else (avoid the standard file descriptors), e.g.:
while IFS= read -r -u3 line; do echo "Text read from file: $line" done 3< "$1"
(Non-Bash shells might not know
read -u3; use
read <&3 instead.)
Read more... Read less...
I encourage you to use the
-r flag for
read which stands for:
-r Do not treat a backslash character in any special way. Consider each backslash to be part of the input line.
I am citing from
man 1 read.
Another thing is to take a filename as an argument.
Here is updated code:
#!/usr/bin/bash filename="$1" while read -r line; do name="$line" echo "Name read from file - $name" done < "$filename"
Using the following Bash template should allow you to read one value at a time from a file and process it.
while read name; do # Do what you want to $name done < filename
#! /bin/bash cat filename | while read LINE; do echo $LINE done
Many people have posted a solution that's over-optimized. I don't think it is incorrect, but I humbly think that a less optimized solution will be desirable to permit everyone to easily understand how is this working. Here is my proposal:
#!/bin/bash # # This program reads lines from a file. # end_of_file=0 while [[ $end_of_file == 0 ]]; do read -r line # the last exit status is the # flag of the end of file end_of_file=$? echo $line done < "$1"
filename=$1 IFS=$'\n' for next in `cat $filename`; do echo "$next read from $filename" done exit 0
If you have set
IFS differently you will get odd results.