I've read that using "for" is not a good way to read lines in bash. Many people says this is clumsy and inefficient at best, and fails in many cases.
I'd like to know what is the best way to read lines in bash. Thanks.
For example:
$ for i in $(Answer
You are talking about for line in $(cat file); do and similar constructs. This is:
- Inefficient because bash has to spawn a subshell and execute
cat, readcat's output – the entire file – into memory, parse it (which is the slowest part), only then iterate over all data - Unreliable because bash performs word-splitting on the data – not only does it split on newline characters, but also on anything in $IFS (spaces, tabs...)
(If you use $(<...) instead of $(cat ...), you save two milliseconds on Linux, but all other downsides remain.)
A much better option is to use read in a while loop:
while read -r line; do
echo "Input: $line"
done < myfile.txt
Or from a program:
cat file1 file2 file3 |
while read -r line; do
echo "Input: $line"
done
This only reads as much as is needed, does not perform unnecessary processing but allows custom field splitting, and is many times faster and less resource-demanding on large files.
If you're trying to work with the output of find, you should use the same pattern:
find . -name "foo" -type f -print0 | while read -r -d '' file; do
echo "File: $file"
done
See also:
Comments
Post a Comment