paulo1205
(usa Ubuntu)
Enviado em 05/08/2016 - 04:50h
Permita-me fazer três considerações, antes de prosseguir com a resposta:
- O shell, quando usado como linguagem de programação, não é famoso por ter bom desempenho. Se você quer processar textos, há ferramentas muito melhores (por exemplo, Perl, AWK e, para casos mais simples, até mesmo
sed e
grep). Houve um tópico aqui na comunidade que deixou isso bem claro (cf.
https://www.vivaolinux.com.br/topico/Shell-Script/Como-criar-um-script-para-localizar-varias-palavra...).
- Se o arquivo for realmente MUITO grande, ler para um array em memória pode ser um problema (i.e. gastar toda a memória).
- O shell é muito limitado com relação às operações de entrada e saída que pode realizar.
Você falou em “fazer o while trabalhar com índices”. Não sei se entendi o que você quer saber, por isso vou falar de várias coisas que podem estar um pouco mais ou um pouco menos relacionadas ao efeito que você quer obter.
O comando
while não trabalha com índices, porque a única coisa que ele testa é se a condição de controle (no seu caso, o resultado do comando
read) é verdadeira ou falsa.
O comando
read trata a entrada como uma fila de dados: ele pega os caracteres de cada linha, e nunca pode voltar atrás nem saltar para frente arbitrariamente. Se você quiser saltar para frente (para trás é totalmente impossível), o único jeito é ler e imediatamente desprezar os elementos da fila que não lhe interessam, até passar a quantidade de elementos sobre as quais você queria saltar. Tem de ser assim porque o shell não tem como saber antecipadamente qual o comprimento de cada linha
O Bash tem dois comandos (aparentemente sinônimos) que permitem ler linhas consecutivas diretamente para um array:
mapfile e
readarray, que inclusive possuem opções que permitem saltar (apenas para frente) dados do arquivo ou iniciar a leitura a partir de uma posição específica do array. Contudo, eu recomendo cautela com esse comando, pois, além do risco de exaurir memória com arquivos muito grandes, tais comandos são incompatíveis com outros sabores de shell (e.g. Bourne Shell tradicional (sh), Korn Shell (ksh, incluindo o ksh93) e as variantes de ambos (dash, ash, pdksh, mksh etc.)).