Extrair palavras correspondentes com o grep no Cygwin

2

Estou usando o Cygwin, então tenho revisado as informações de regex do POSIX.

Estou tentando pesquisar em um arquivo xml por uma string e continuo recebendo a linha inteira, mas não consigo restringir os resultados aos poucos caracteres que estou procurando.

O arquivo (file1) tem muitas instâncias de:

<!ENTITY abc123456 SYSTEM "../blah/abc123456.xyz" NDATA xyz>
<!ENTITY abc123457 SYSTEM "../blah/abc123457.xyz" NDATA xyz>
<!ENTITY abc123458 SYSTEM "../blah/abc123458.xyz" NDATA xyz>

Os resultados do grep listam toda a linha, mas estou tentando restringir os resultados a:

abc123456.xyz
abc123457.xyz
abc123458.xyz

O seguinte com sucesso me fornece as linhas:

grep -E abc[[:digit:]] file1
grep abc[0-9] file1
grep "abc[[:digit:]]" file1

Como o que estou procurando não está no começo nem no final de uma linha, ^ e $ não parecem ser úteis. Não sei como ancorar o que estou procurando. Eu tentei algumas outras variações do uso do grep sem sucesso.

    
por regexnoob 25.02.2017 / 17:33

2 respostas

2

Deve haver soluções mais elegantes (talvez grep -P seja uma?), mas você pode usar sed para simular grep e obter as sequências desejadas nos casos em que um simples grep -o não seja suficiente:

sed -nr 's/.*SYSTEM "..\/blah\/([^"]*).*//p'

Isso basicamente corresponderá à string inteira e, em seguida, a substituirá totalmente pela substring que você estava procurando.

    
por 25.02.2017 / 17:46
0

O comando grep imprime linhas contendo uma correspondência. Não importa o padrão que você usa para corresponder a uma parte da linha, o grep imprime toda a linha.

O GNU grep, que é a versão incluída no Cygwin, tem a opção de exibir apenas a parte da linha correspondente ao padrão: -o .

grep -o 'abc[0-9][^"]*' file1

Você pode adicionar \b no início do padrão para corresponder apenas após espaço em branco ou pontuação, ou seja, para evitar corresponder /fooabc123.xyz . Se você quiser corresponder especificamente após um / ou " , o caractere de pontuação será incluído na saída; você pode evitar isso com uma asserção lookbehind que está disponível em Perl regex sintaxe.

grep -o -P '(?<=[/"])abc[0-9][^"]*' file1
    
por 27.02.2017 / 01:16