Como encontrar / grep o que está entre string1 e string2?

2

Estou tentando extrair um valor de uma cadeia longa que pode mudar com o tempo. Então, por exemplo, a string poderia ser algo como isto

....../filename-1.9.0.3.tar.gz"<....

E o que eu quero extrair é o valor entre filename - e .tar.gz , essencialmente a versão do arquivo (1.9.0.3 neste caso). A razão pela qual eu preciso fazer isso é porque eu posso mais tarde executar o comando e o valor será 1.9.0.6 ou 2.0.0.2 ou algo totalmente diferente.

Como posso fazer isso? Atualmente, estou usando apenas o grep, mas não me importaria de usar outros utilitários como sed, awk, cut ou qualquer outra coisa. Para ser perfeitamente claro, eu preciso extrair apenas a parte da versão do arquivo da string, já que é muito longo (em ambos os lados) todo o resto precisa ser cortado de alguma forma.

    
por Cestarian 01.03.2016 / 23:43

2 respostas

4

Com grep -P / pcregrep , usando uma perspectiva positiva e uma perspectiva positiva:

grep -P -o '(?<=STRING1).*?(?=STRING2)' infile

no seu caso, substitua STRING1 por filename- e STRING2 por \.tar\.gz

Se você não tem acesso a pcregrep e / ou se o grep não suporta -P , você pode fazer isso com sua ferramenta de processamento de texto favorita. Aqui está uma maneira portátil com ed que fornece a mesma saída:

ed -s infile <<\IN
g/STRING1/s//\ 
&/g
v/STRING1.*STRING2/d
,s/STRING1//
,s/STRING2.*//
,p
IN

Como funciona: uma nova linha é anexada a cada STRING1 ocorrência (então agora há no máximo uma ocorrência por linha), então todas as linhas que não coincidirem com STRING1.*STRING2 serão excluídas; nos restantes, mantemos apenas o que está entre STRING1 e STRING2 e imprimimos o resultado.

    
por 01.03.2016 / 23:53
1

Para o benefício de pessoas sem grep -P , você pode fazer isso com sed ou awk em qualquer sistema POSIX.

sed -n -e 's/^.*\/filename-\([^\/]*\)\.tar\.gz.*$//p' -e T -e q

Explicação: desative a impressão padrão, localize uma linha contendo o padrão desejado e substitua tudo, exceto a parte que deseja manter, imprima o resultado da substituição e saia se houver uma correspondência. Observe que, se houver várias correspondências na primeira linha correspondente, ela pegará a última.

Com awk (escolhendo o primeiro jogo na linha):

awk 'match($0, /filename-[^/]*\.tar\.gz/) {
    print substr(RSTART + 9, RSTART + RLENGTH - 9 - 6, $0);
    exit;
}'
    
por 02.03.2016 / 02:34