I want to do the following: Read a file line by line and use the line as a parameter.
FILE="cat test" echo "$FILE" | \ while read CMD; do echo $CMD done
But when I do echo $CMD
, it just prints cat test
.
Syntax: Read file line by line on a Bash Unix & Linux shell file. The -r option passed to read command prevents backslash escapes from being interpreted. Add IFS= option before read command to prevent leading/trailing whitespace from being trimmed. while IFS= read -r line; do COMMAND_on $line; done < input.
In Bash, you can use a while loop on the command line to read each line of text from a file and do something with it. Our text file is called “data. txt.” It holds a list of the months of the year. The while loop reads a line from the file, and the execution flow of the little program passes to the body of the loop.
We can use the read command to read the contents of a file line by line. We use the -r argument to the read command to avoid any backslash-escaped characters. In the following example, we can see that we have an iteration over a file line by line and we store the contents of a single line in the variable “line“.
The while read loop. Here, cat reads each line from standard input and writes the line to standard output. It continues until the end-of-file condition is reached on file1, then it stops. In shell programming, we can read a line from standard input using the read command.
The best way to do this is to redirect the file into the loop:
# Basic idea. Keep reading for improvements. FILE=test while read CMD; do echo "$CMD" done < "$FILE"
A redirection with < "$FILE"
has a few advantages over cat "$FILE" | while ...
. It avoids a useless use of cat, saving an unnecessary child process. It also avoids a common pitfall where the loop runs in a subshell. In Bash, commands in a |
pipeline run in subshells, which means variable assignments are lost after the loop ends. Redirection with <
doesn't have that problem, so you could use $CMD
after the loop or modify other variables inside the loop. It also, again, avoids unnecessary child processes.
There are some additional improvements that could be made:
IFS=
so that read
won't trim leading and trailing whitespace from each line.-r
to read
to prevent backslashes from being interpreted as escape sequences.CMD
and FILE
. The Bash convention is that only environmental and internal shell variables are uppercase.printf
in place of echo
which is safer if $cmd
is a string like -n
, which echo
would interpret as a flag.file=test while IFS= read -r cmd; do printf '%s\n' "$cmd" done < "$file"
What you have is piping the text "cat test"
into the loop.
You just want:
cat test | \ while read CMD; do echo $CMD done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With