Como encontro a string após um regexp em uma única linha de texto?

0

Eu tenho um arquivo de texto contendo uma linha muito longa de dados JSON e preciso extrair o valor de algum campo. Eu percebo que a maneira mais fácil de fazer isso seria usar jq ou grep -o ; no entanto, estou em uma máquina da empresa, portanto não posso instalar o jq e estamos usando uma versão do Solaris em que grep não possui a opção -o . Atualmente estou usando o comando:

cat json.file   |
    tr "," "\n" |
    awk '/customfield_10701/ { print $0 }' |
    tr '"' "\n" |
    awk 'NR==4'

O acima funciona bem, mas não posso deixar de sentir que é excessivamente complicado e que deveria haver uma solução mais elegante.

Exemplo de json.file :

... jshdgfjhsdgfjh,"customfield_10701":"Some Branch","customfield_10702ksghdkfsdkfjkj ...

Com o meu comando atual, recebo:

Some Branch

(que é o que eu quero).

    
por Void 13.06.2016 / 17:50

3 respostas

3

Se tiver certeza de que não há caracteres " nos dados que você está procurando e se há apenas uma linha contendo uma entrada "customfield_10701" no arquivo, então

sed -n 's/.*"customfield_10701":"\([^"]*\)".*//p'

por exemplo,

$ cat x
... jshdgfjhsdgfjh,"customfield_10701":"Some Branch","customfield_10702ksghdkfsdkfjkj ...
$ sed -n 's/.*"customfield_10701":"\([^"]*\)".*//p' x
Some Branch
    
por 13.06.2016 / 18:03
0

Você não precisa usar tr para transformar vírgulas em novas linhas. E depois de volta novamente. Você pode dizer a awk para usar uma vírgula como o Separador de Registro de Entrada ( RS ).

awk -F':' -v RS=',' '/customfield_10701/ { gsub(/"/,"",$2); print $2 }' json.file

gsub() é usado para remover aspas duplas " (se houver) do campo 2.

Se necessário, você também pode usar gsub() para remover espaços e tabulações iniciais e finais:

awk -F':' -v RS=',' '/customfield_10701/ {
    gsub(/"|^[[:blank:]]+|[[:blank:]]+$/,"",$2);
    print $2
}' json.file

Observe que o Separador do Registro de Saída ( ORS ) não é alterado automaticamente quando RS é alterado, ele permanece no padrão (uma nova linha), a menos que você o defina (por exemplo, com -v ORS=',' ).

    
por 14.06.2016 / 10:18
0

O teste a seguir funciona para mim usando bash 3 incorporado ao mecanismo de regex e não requer programas externos:

json='"jshdgfjhsdgfjh,"customfield_10701":"Some Branch","customfield_10702ksghdkfsdkfjkj"'

regex_hint=customfield_10701

[[ $json =~ $regex_hint\":\"(.+)\", ]] && printf '%s\n' "${BASH_REMATCH[1]}" 

Impressões: algum ramo

O regex entre '()' é o "grupo de captura 1", que é salvo em "$ {BASH_REMATCH 1 } "

Observe que o bash embutido suporta Expressões regulares estendidas POSIX em vez das mais conhecidas Perl Expressões regulares compatíveis

    
por 14.06.2016 / 22:32