Eu analisei outras respostas, mas não consegui obter uma explicação adequada de como fazer isso.
Eu tem uma variável de string chamada id
de modo que id="{"name":"john"}"
. Como posso obter 2 variáveis dessa string como-
key="name" value="john"
Uma explicação detalhada seria apreciada, pois desejo entender a análise de strings no bash.
Até agora, removi as chaves {}
da string-
id="$( echo "${id}" | tr -d {} )"
Não posso” t incluir "
lá como ele gera um erro. Também procurando por algo como id.split(":")
no final para obter uma matriz.
Comentários
Resposta
Usando jq
:
id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id")
-r
: Com esta opção, se o filtro “s o resultado é uma string, então ele será escrito diretamente na saída padrão em vez de ser formatado como uma string JSON com aspas.
keys
: As teclas de função incorporadas, quando dado um objeto, retorna suas chaves em uma matriz.
Usando json
:
id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id")
-a
processa a entrada como uma matriz
-k
retorna os valores-chave
Comentários
- obrigado pela explicação. Funciona muito bem. Acho que ‘ não há como analisar uma string sem
jq
em scripts bash. - @kev: Existem várias maneiras de analisar strings, mas ‘ é meio injusto para chamar isso de string e não de dados json.
- Os dados JSON @kev podem ser codificados. Para analisá-lo, você potencialmente teria que decodificá-lo. Além disso, JSON não se preocupa com espaços em branco (novas linhas etc.) entre chaves e valores, então você deve levar isso em consideração. Isso já foi feito para você pelos autores do analisador JSON subjacente em
jq
.
Resposta
Você literalmente pediu para understand string parsing in bash
, então vou escrever uma resposta com isso em mente, mesmo que seja solução errada para o seu problema . Você pode usar o próprio bash para fazer o que quiser, se tiver realmente limpo dados sem caracteres especiais, onde especial é definido como qualquer coisa fora de [A-Za-z0-9 ]
:
$name":"john"}" $ # remove everything through the first "{" $ echo $id "name":"john"} $ # remove everything starting with the last "}" $ echo $id "name":"john" $ name="${id%:*}" # take everything before the ":" $ name="${name//\"/}" # remove quotes $ echo $name name $ value="${id#*:}" # take everything after the ":" $ value="${value//\"/}" # remove quotes $ echo $value john
Tudo isso está descrito em “Expansão de parâmetros” no manual do bash . Por exemplo, ${parameter#word}
que Remove matching prefix pattern
removerá o texto word
do início de $parameter
. Da mesma forma, %
remove o sufixo. //
substitui todas as ocorrências de uma string com o que vier depois dela (no ${foo//\"/}
exemplo acima, aspas (que devem ser escapadas, então aparecem como \"
) são substituídos pela string vazia). No entanto, você deve realizar cada substituição por si só: você não pode remover o início e o final da string com um comando.
Você provavelmente também percebeu que precisa escapar caracteres especiais, como }
, {
e "
. Contanto que você se lembre de acertar, você pode escrever código como este com bastante facilidade, mas, por mais simples que seja, tende a ser um código somente para escrita. Quando você voltar a este código em um ou dois anos para reutilizá-lo, você “verá algo como #*\{}
e pensará consigo mesmo: WTF isso significa? e em seguida, basta copiá-lo cegamente para um novo projeto e então seu código irá quebrar de uma maneira sutil porque encontra caracteres especiais que você não esperava.
Os exemplos acima serão interrompidos se seus pares nome-valor tiverem caracteres especiais, como colchetes ou aspas de escape ou dois pontos ou provavelmente outros caracteres. Portanto, isso funcionará bem para alguma eliminação rápida e suja ou para o caso de uso de 80%, mas você realmente não deve usá-lo na produção ou a qualquer momento que precisar ter certeza de que sempre funcionará com qualquer entrada.
Mesmo sem as echo
instruções lá para mostrar o que está acontecendo, você pode ver que este código já é mais longo do que os exemplos na outra resposta que mostram como fazer apropriadamente. Portanto, ao não usar uma ferramenta de terceiros, você está dando a si mesmo mais código para escrever, o que levará mais tempo para escrever e depurar, e você também está terminando com uma solução que é menos flexível e que irá interromper quando encontrar algo inesperado.
Comentários
- isso foi bastante informativo – pode ‘ t compreender por que as pessoas votariam negativamente
Resposta
Alternativamente, você poderia usar um unix baseado em walk-path utilitário jtc
:
id="{"name":"john"}" bash $ key=$(jtc -w"[0]<>k" <<<"$id") bash $ echo $key "name" bash $ value=$(jtc -w"[0]" <<<"$id") bash $ echo $value "john" bash $
PS> Divulgação: eu “sou o criador da jtc
– ferramenta shell cli para operações JSON
jq
é usado por outras pessoas, mas não há como eu analisar isso sem um terceiro ferramenta?awk
,sed
egrep
também são ferramentas de terceiros. Se você estiver usandojson
dados, não há absolutamente nenhuma razão para não ter as ferramentas adequadas para trabalhar com eles.