I have a text file like
line2
line3;
line4
line5
line6
line7;
I need a loop to read the line till ; on each loop. on the first loop read up to line3; and on the second loop up to line7; and so on. no need to merge the lines into a single one
CodePudding user response:
Consider telling read
to stop on ;
instead of on newlines, and instead to use newlines to delimit individual input items (when using -a
to read into an array, this makes each line an array element).
while IFS=$'\n' read -r -d ';' -a lines; do
echo "Read group of lines:"
printf ' - %s\n' "${lines[@]};"
done
...emits as output:
Read group of lines:
- line2
- line3;
Read group of lines:
- line4
- line5
- line6
- line7;
You can, if you choose, replace the printf with something like for line in "${lines[@]}"; do
to create an inner loop to operate on lines within a group one-by-one.
CodePudding user response:
You can use two loops: one to continue until the end of the file, and an inner loop to read individual lines until you find one that ends with a ;
.
For example,
while :; do
lines=()
while IFS= read -r line; do
lines =( "$line" )
if [[ $line = *; ]]; then
break
fi
done
if (( ${#lines[@]} == 0 )); then
# The previous loop didn't add anything to the array,
# so the last read must have failed, and we've reached
# then end of the file
break
done
# do something with $lines
done < file.txt
Or, use one loop that pauses to use lines when one ending with a ;
is found:
lines=()
while IFS= read -r line; do
lines =("$line")
if [[ $line = *; ]]; then
# do stuff with lines, then clear the array
lines=()
fi
done < file.txt
# If applicable, do something with the last batch of lines
# if the file doesn't end with a ;-terminated line.