encontra um padrão de string específico de um arquivo no Unix Shell Scripting

1

Eu tenho o comando abaixo.

 unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | grep  ":taxonomies-" | head -1

que me dá a saída como,

    <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>

No entanto, preciso extrair apenas taxonomies-8.2.0 em vez da string completa, conforme acima.

    
por Atil Thakor 21.10.2014 / 18:14

2 respostas

1

Uma maneira é usar a opção -o do grep, combinada com o poder de PCREs ( -P ):

   -o, --only-matching
          Print  only  the  matched  (non-empty) parts of a matching line,
          with each such part on a separate output line.
   -P, --perl-regexp
          Interpret  PATTERN  as  a  Perl  regular  expression  (PCRE, see
          below).  This is highly experimental and grep  -P  may  warn  of
          unimplemented features.

Então, você poderia fazer

 unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | grep -oP ':\Ktaxonomies-[^"]*' | head -1

O \K faz com que qualquer coisa correspondente a esse ponto seja ignorada (portanto, o : não é impresso) e [^"]*" significa "corresponde a tantos caracteres que não são " .

Outras opções incluem:

  1. sed

    unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | 
        sed -n 's/.*:\(taxonomies-[^"]*\).*//p' | head -1
    

    O -n faz com que sed imprima nada, a menos que explicitamente informado e o s/// seja o operador de substituição. Ele substituirá tudo na linha pela parte da linha entre os parênteses ( ). O p faz com que a linha resultante seja impressa.

  2. Perl

    unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | 
      perl -lne 's/.*:(taxonomies-[^"]).*/$1/ && print' | head -1
    

    A mesma ideia básica do sed . Se a substituição foi bem sucedida, a linha é impressa. Uma alternativa seria

    unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | 
      perl -lne '/.*:(taxonomies-[^"])/ && print $1' | head -1
    
por 21.10.2014 / 18:27
1

Se você souber a ocorrência do caracter : em sua entrada, poderá fazer algo assim.

echo " <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>" | 
awk -F\: '{print $4}' | sed 's/..$//'

O comando awk imprime a string th após o delimitador : e o comando sed é usado para remover os últimos 2 caracteres para obter a saída desejada .

No entanto, se esse método funcionar ou não, depende de sua entrada como terdon aponta em seus comentários .

EDITAR

O pipe final para sed poderia muito bem ser evitado se usarmos a solução sugerida por jasonwryan em os comentários . Então, o comando seria efetivamente reformulado como,

 echo " <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>" | 
 awk -F: '{sub(/\/>/,""); print $4}'

Outra solução usando apenas corte e rev pode ser enquadrada como

echo " <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>" | 
cut -d ':' -f4 | rev | cut -c 3- | rev

Novamente, a especificação do delimitador depende do arquivo de entrada e do exemplo fornecido, os caracteres que preciso extrair ocorrem após a posição 4 th do delimitador. Eu uso cut para extrair a substring após este 4 th delimitador e usar a boa e velha técnica rev para reverter a string e remover os 3 últimos caracteres e novamente aplicar rev nela para obter o seqüência real.

    
por 21.10.2014 / 18:29