Estou adicionando uma nova resposta agora que entendi melhor o problema. Estou apenas postando isso como um exemplo de trabalho, mas não afirmo que seja um bom exemplo. :)
Além disso, eu entendo que a pergunta parecia não usar o Python por causa de alguns medos de ineficiência. Então, entendo que essa abordagem não atende a solicitação inteira. : (
#!/usr/bin/env python
import sys
def findall_iter(S, pat):
index = -1
while True:
try:
index = S.index(pat, index+1)
yield index
except ValueError:
raise StopIteration
def findall(S, pat):
return list(findall_iter(S, pat))
# read in arguments
S = open(sys.argv[2]).read()
pattern = sys.argv[1]
# get indices of all newlines
newline_indices = findall(S, '\n')
# get psudo-indices of all pattern matches
pat_indices = findall(S.replace('\n', ''), pattern)
# iterate through each pattern match psudo-index and
# correlate it back to a real line number from the file
line_numbers = []
for pi in pat_indices:
for i, ni in enumerate(newline_indices):
if ni > pi+i:
line = i + 1
if line not in line_numbers:
line_numbers.append(i+1)
break
print '\n'.join(map(str, line_numbers))
Prós:
- Se o arquivo não for muito grande (< 1GB), todas as operações serão realizadas na memória.
- Usa o método str.index para localizar substrings em vez de correspondência de expressão regular (mais lenta)
- Mais claro do que usar expressões regulares
Contras:
- não funciona bem com arquivos grandes.
- Cria duas strings temporárias para fazer o trabalho.
- O último for-loop é difícil de entender.
- É o Python (que eu pessoalmente não acho que seja um engodo).