You need to make some changes to your script (in no particular order):
- Use
IFS=
before read
to avoid removing leading and trailing spaces.
- As
$line
is not changed anywhere, there is no need for variable readLine
.
- Do not use read in the middle of the loop!!.
- Use a Boolean variable to control printing.
- Make clear the start and end of printing.
With those changes, the script becomes:
#!/bin/bash
filename="foo.txt"
#While loop to read line by line
while IFS= read -r line; do
#If the line starts with ST then set var to yes.
if [[ $line == qwe* ]] ; then
printline="yes"
# Just t make each line start very clear, remove in use.
echo "----------------------->>"
fi
# If variable is yes, print the line.
if [[ $printline == "yes" ]] ; then
echo "$line"
fi
#If the line starts with ST then set var to no.
if [[ $line == ewq* ]] ; then
printline="no"
# Just to make each line end very clear, remove in use.
echo "----------------------------<<"
fi
done < "$filename"
Which could be condensed in this way:
#!/bin/bash
filename="foo.txt"
while IFS= read -r line; do
[[ $line == qwe* ]] && printline="yes"
[[ $printline == "yes" ]] && echo "$line"
[[ $line == ewq* ]] && printline="no"
done < "$filename"
That will print the start and end lines (inclusive).
If there is no need to print them, swap the start and end tests:
#!/bin/bash
filename="foo.txt"
while IFS= read -r line; do
[[ $line == ewq* ]] && printline="no"
[[ $printline == "yes" ]] && echo "$line"
[[ $line == qwe* ]] && printline="yes"
done < "$filename"
However, it would be quite better (if you have bash version 4.0 or better) to use readarray
and loop with the array elements:
#!/bin/dash
filename="infile"
readarray -t lines < "$filename"
for line in "${lines[@]}"; do
[[ $line == ewq* ]] && printline="no"
[[ $printline == "yes" ]] && echo "$line"
[[ $line == qwe* ]] && printline="yes"
done
That will avoid most of the issues of using read
.
Of course, you could use the recommended (in comments; Thanks, @costas) sed
line to get only the lines to be processed:
#!/bin/bash
filename="foo.txt"
readarray -t lines <<< "$(sed -n '/^qwe.*/,/^ewq.*/p' "$filename")"
for line in "${lines[@]}"; do
: # Do all your additional processing here, with a clean input.
done
sed '/qwe/,/ewq/ w other.file' foo.txt
while..read
you're almost always doing it wrong.