Revisé otras respuestas pero no pude obtener una explicación adecuada de cómo hacer esto.
Yo tener una variable de cadena llamada id
tal que id="{"name":"john"}"
. ¿Cómo puedo obtener 2 variables de esta cadena como-
key="name" value="john"
Se agradecería una explicación detallada ya que quiero comprender el análisis de cadenas en bash.
Hasta ahora, «he eliminado las llaves {}
de la cadena-
id="$( echo "${id}" | tr -d {} )"
No puedo» incluir "
allí como arroja un error. También busca algo como id.split(":")
al final para obtener una matriz.
Comentarios
Respuesta
Usando jq
:
id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id")
-r
: con esta opción, si el filtro «s el resultado es una cadena, entonces se escribirá directamente en la salida estándar en lugar de formatearse como una cadena JSON con comillas.
keys
: las teclas de función integradas, cuando dado un objeto, devuelve sus claves en una matriz.
Usando json
:
id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id")
-a
procesa la entrada como una matriz
-k
devuelve valores clave
Comentarios
- gracias por la explicación. Funciona muy bien. Creo que ‘ s no hay forma de analizar una cadena sin
jq
en scripts bash. - @kev: Hay muchas formas de analizar cadenas, pero es ‘ un poco injusto para llamar a esto una cadena y no datos json.
- @kev Los datos JSON se pueden codificar. Para analizarlo, potencialmente tendría que decodificarlo. Además, JSON no se preocupa por los espacios en blanco (líneas nuevas, etc.) entre claves y valores, por lo que debería tenerlo en cuenta. Esto ya lo han hecho los autores del analizador JSON subyacente en
jq
.
Respuesta
Literalmente pediste understand string parsing in bash
, así que escribiré una respuesta con eso en mente, aunque sea el solución incorrecta para su problema . Puedes usar bash para hacer lo que quieras, si tienes realmente limpio datos sin caracteres especiales, donde especial se define como cualquier cosa fuera 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
Todo esto se describe en «Expansión de parámetros» en el manual de bash . Por ejemplo, ${parameter#word}
que Remove matching prefix pattern
eliminará el texto word
del comienzo de $parameter
. De manera similar, %
elimina el sufijo. //
reemplaza todas las apariciones de una cadena con lo que venga después (en el ${foo//\"/}
ejemplo anterior, las comillas (que deben escaparse) aparecen como \"
) se reemplazan con la cadena vacía). Sin embargo, debe realizar cada sustitución por sí sola: no puede eliminar el principio y de la cadena con un comando.
Probablemente también haya notado que necesita escapar de caracteres especiales, como }
, {
y "
. Siempre que recuerde hacerlo bien, puede escribir código como este con bastante facilidad, pero, por simple que sea, tiende a ser código de solo escritura. Cuando vuelva a esto código en un año o dos para reutilizarlo, «mirarás algo como #*\{}
y pensarás, WTF, ¿eso siquiera significa? y luego simplemente cópielo a ciegas en un nuevo proyecto y luego su código se romperá de una manera sutil porque encuentra caracteres especiales que no esperaba.
Los ejemplos anteriores se romperán si los pares de nombre-valor tienen caracteres especiales, como llaves, comillas o dos puntos de escape o probablemente otros caracteres. Así que esto funcionará bien para un raspado rápido y sucio o para el caso de uso del 80%, pero realmente no debería usarlo en producción o en cualquier momento que necesite asegurarse de que siempre funcione con cualquier entrada.
Incluso sin las echo
declaraciones allí para mostrarle lo que está sucediendo, puede ver que este código ya es más largo que los ejemplos en la otra respuesta que muestran cómo hacerlo adecuadamente. Entonces, al no usar una herramienta de terceros, se está dando más código para escribir, lo que le llevará más tiempo escribir y depurar, y también terminará con una solución que es menos flexible y que romperse cuando encuentra algo inesperado.
Comentarios
- esto fue bastante informativo – can ‘ t comprender por qué la gente votaría en contra
Responder
Alternativamente, podría usar un Unix basado en walk-path utilidad 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> Divulgación: Soy el creador de la jtc
– herramienta shell cli para operaciones JSON
jq
es usado por otros, pero no hay forma de que pueda analizar esto sin un tercero herramienta?awk
,sed
ygrep
también son herramientas de terceros. Si está utilizandojson
datos, no hay absolutamente ninguna razón para no tener las herramientas adecuadas para trabajar con ellos.