Como imprimir uma linha que é seguida por uma string específica em um arquivo repetitivo?

2

Esta é a minha primeira pergunta e espero que você possa me ajudar. Eu pesquisei como fazer isso, mas não encontrei uma solução.

Eu tenho um arquivo de texto com milhares de repetições como esta:

Query= AX-1  
[some lines without pattern]                                                             
A1
B2
C3
R7                                        

Query= AX-2 
[some lines without pattern]                                                                                                     
A1
F5  

Query= AX-3
[some lines without pattern]                                                                                                      
S9
T4
F5

Eu preciso imprimir todas as consultas que contêm uma string específica. Por exemplo, se eu procurar por F5 , devo receber:

AX-2
AX-3

e procurando A1 devem imprimir:

AX-1
AX-2

Acho que isso pode ser feito com uma pesquisa condicional que imprima a primeira linha anterior, começando com "Consulta". Mas qualquer maneira de fazer isso seria incrível.

    
por Nicolas Salcedo 31.05.2016 / 18:44

2 respostas

0

Em um pequeno script python :

#!/usr/bin/env python3
import sys
s = sys.argv[1]; f = sys.argv[2]

currqu = ""
with open(f) as src:
    for l in src:
        if l.startswith("Query"):
            currqu = l.split()[-1].strip()
        if l.strip() == s:
            print(currqu)

Para usar

  1. Copie o script em um arquivo vazio, salve-o como quer.py
  2. execute-o com a string (por exemplo, F5) e o arquivo de texto como argumentos:

    python3 /path/to/quer.py F5 /path/to/file.txt
    

Se o caminho contiver espaços, use aspas em torno dele.
Como ele lê por linha, deve ser bem rápido em arquivos grandes (grandes).

Como funciona

  • ele lê as linhas, procurando por uma linha, começando com Query
  • se assim for, manterá o valor na linha "em mente", até a próxima ocorrência de "Consulta"
  • entre procura sua string procurada, imprime o valor de "Consulta" se ocorrer, efetivamente procurando "para trás" em caso afirmativo.

EDITAR

Conforme solicitado em um comentário, uma versão que procura

  • várias correspondências em um comando.

e o script

  • elimina duplicados .

Cria uma saída como:

$ '/home/jacob/Bureaublad/pscript_3.py' '/home/jacob/Bureaublad/look.txt' A1 F5
[A1]
AX-1
AX-2
[F5]
AX-2
AX-3

O script

#!/usr/bin/env python3
import sys
strs = sys.argv[2:]; f = sys.argv[1]

for s in strs:
    print("["+s+"]")
    output = []; currqu = ""
    with open(f) as src:
        for l in src:
            if l.startswith("Query"):
                currqu = l.split()[-1].strip()
            if l.strip() == s:
                output.append(currqu)
        for item in sorted(set(output)):
            print(item)

Como usar

Quase o mesmo que o primeiro script, mas agora, inicie com o arquivo como argumento e, em seguida, as seqüências de caracteres. Em princípio, você pode ter quantas strings desejar em um comando.

python3 /path/to/quer.py /path/to/file.txt F5 A1 B6 C7

etc, etc.

    
por Jacob Vlijm 31.05.2016 / 19:06
1

Este comando do awk pode fazer o trabalho:

awk -v RS='\n\n' -v target=<string> '$0 ~ target {print $2}'

Por exemplo:

$ awk -v RS='\n\n' -v target=F5 '$0 ~ target {print $2}' foo.txt 
AX-2
AX-3
$ awk -v RS='\n\n' -v target=A1 '$0 ~ target {print $2}' foo.txt
AX-1
AX-2

Estou assumindo que:

  1. as seções Consulta são todas separadas por linhas em branco (portanto, duas novas linhas \n\n como separador de registro),
  2. há um espaço após o Query= , para que a sequência que você deseja imprimir seja o segundo campo ( $2 ),
  3. a string que você deseja pesquisar não possui caracteres especiais de regex como . ou * . Se assim for, outra função pode ter que ser usada.
por muru 31.05.2016 / 19:05