Você precisa fazer algumas alterações no seu script (em nenhuma ordem específica):
- Use
IFS=
antes deread
para evitar a remoção de espaços iniciais e finais. - Como
$line
não é alterado em lugar nenhum, não há necessidade da variávelreadLine
. - Não use a leitura no meio do loop !!.
- Use uma variável booleana para controlar a impressão.
- Deixe claro o início e o fim da impressão.
Com essas alterações, o script se torna:
#!/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"
O que poderia ser condensado desta maneira:
#!/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"
Isso imprimirá as linhas inicial e final (inclusive). Se não houver necessidade de imprimi-los, troque os testes de início e fim:
#!/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"
No entanto, seria bem melhor (se você tiver o bash versão 4.0 ou melhor) usar readarray
e fazer um loop com os elementos do array:
#!/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
Isso evitará a maioria dos problemas de usar read
.
É claro que você pode usar a linha recomendada (em comentários; Obrigado, @costas) sed
para obter apenas as linhas a serem processadas:
#!/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