Não faça isso em um loop de shell, awk
fará isso por você.
Este é um script awk
que você pode armazenar em um arquivo de script e invocar com awk -f script.awk filename
(modificado para funcionar com a edição recente da pergunta):
BEGIN { lookfor[0] = "foo"; lookfor[1] = "bar"; i = 0 }
$0 ~ lookfor[i] {
lines[lookfor[i]] = lines[lookfor[i]] ? lines[lookfor[i]] ", " NR : NR
i = (i + 1) % 2
}
END { for (n in lines) printf("%s\t%s\n", n, lines[n]) }
Executando isso nos seus dados de exemplo:
$ awk -f script.awk file
foo 1, 12
bar 5, 18
O script awk
procura as strings na matriz lookfor
. Primeiro, ele procura pela primeira string ( foo
) e, quando a encontra, começa a procurar pela segunda string ( bar
) e, em seguida, a primeira novamente de maneira alternada. Cada vez que encontra uma string, ele armazena o número da linha atual na matriz associativa lines
para a string correspondente.
No final, os números de linha coletados em lines
são exibidos.
A linha de aparência descolada
lines[lookfor[i]] = lines[lookfor[i]] ? lines[lookfor[i]] ", " NR : NR
adiciona o número da linha ao final da sequência de números de linha na matriz lines
. Se a string estiver vazia, ela apenas ajusta para o número da linha atual, mas se ela já contiver alguma coisa, uma vírgula é inserida entre a string existente e o número da linha.
Você pode mudar isso para o mais simples
lines[lookfor[i]] = lines[lookfor[i]] " " NR
que irá inserir um espaço entre os números de linha (e na frente do número da primeira linha).