Analise uma string no script bash

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

  • Podemos avisá-lo sobre esta tática / faixa antes que ‘ seja tarde demais? Parece que você tem json ou algum outro dado estruturado lá; talvez uma ferramenta dedicada seria uma maneira mais segura de chegar onde você está indo?
  • Eu vi que jq é usado por outras pessoas, mas não há como eu analisar isso sem um terceiro ferramenta?
  • Você está trazendo esses dados de um arquivo? Pode haver mais de um par de chave / valores? Como seria uma aspa dupla como parte do valor?
  • @kev: Tecnicamente awk, sed e grep também são ferramentas de terceiros. Se você estiver usando json dados, não há absolutamente nenhuma razão para não ter as ferramentas adequadas para trabalhar com eles.
  • Esses dados são o resultado de um comando que eu executado em meu script. Será sempre neste formato – 1 chave e 1 valor.

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

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *