Procurando um arquivo de texto com uma única linha usando expressões regulares

5

até onde eu sei, todos os utilitários de processamento de texto unix estão lendo uma linha de cada vez e realizando uma ação nesta linha.

Eu tenho um arquivo enorme com uma única linha de texto que contém vários tokens com os quais estou preocupado.

Você pode pensar no conteúdo do arquivo como algo assim: xzxzxzzxzxAxzzBxzxCzxxzxxzxzzxzxzAzBzxxxxzzCzxzxzxzxzxxzz

Eu quero pegar as duas strings entre (A e B) e (B e C) para cada ocorrência de A. * B. * C. Neste exemplo, minha saída desejada seria esta:

xzz xzx

z zxxxxzz

Como faço isso?

edite: desculpe, não deixei claro. A, B e C são longas cadeias de caracteres que só podem ser identificadas por expressões regulares.

    
por Justus1 12.12.2010 / 18:13

3 respostas

4

Tenho certeza de que há muitas respostas interessantes usando awk , perl , sed e outros. Aqui está uma opção bastante simplista que usa tr para transformar este problema de volta em um problema que sabemos como resolver - encontrar um padrão dentro de uma linha:

 $ tr 'C' '\n' <test.file | sed -n 's/.*A\(.*\)B\(.*$\)/ /p'

O comando tr 'C' '\n' traduz qualquer "C" na entrada em um caractere de nova linha. Assim, é necessário apenas canalizá-lo para um comando que produzirá o texto entre A e B e entre B e o fim da linha.

Se A, B e C forem expressões regulares em vez de caracteres simples, tente:

sed -e 's/C/\n/g' < test.file | sed -n 's/.*A\(.*\)B\(.*\)/ /p'

Isso usa a mesma ideia básica, mas usa sed para criar as novas linhas.

    
por 12.12.2010 / 18:41
2

Awk generaliza a noção de linhas para gravar, que pode ser terminada por qualquer caractere. Várias implementações, como o Gawk , suportam uma expressão regular arbitrária como o separador de registros. Não testado:

gawk -vRS='C' 'sub(/.*A/, "") && sub(/B.*/) {print}'
    
por 12.12.2010 / 19:08
0

Se a linha puder caber na memória, o uso repetido da função de divisão do Perl funcionaria. Caso contrário, eu leria o arquivo em blocos (com a função sysread do Perl) e processaria cada bloco individualmente como acima - permitindo que os stings de interesse cruzassem os limites do bloco.

    
por 12.12.2010 / 18:31