BASH Cómo mejorar el rendimiento del análisis de JSON con jq
Contexto: Tengo un escenario en el que necesito realizar copias de seguridad de un sistema a otro. Quiero que la lista de copias de seguridad sea configurable, por lo que opté por un enfoque JSON dentro del propio script.
La lista contiene una clave (nombre de la copia de seguridad para mostrar en la salida), el usuario para hacer SSH y la ruta desde la que obtener la copia de seguridad.
Ejemplo:
sh
backups_to_perform='[
{
"key": "key1",
"user": "user1",
"path": "path1"
},
{
"key": "key2",
"user": "user2",
"path": "path2"
},
{
"key": "key3",
"user": "user3",
"path": "path3"
},
]'
La razón por la que uso JSON es porque quería tener una estructura similar a un diccionario de Python, ya que las matrices asociativas solo pueden tener clave: valor
, en lugar de clave{clave: valor; clave: valor}
(Por favor, corríjame si me equivoco)
Así es como estoy analizando el JSON:
sh
while read -r backup; do
IFS=, read -r key user path <<<"$(jq -cr '"(.key),(.user),(.path)"' <<<"$backup")"
rsync_backup "$key" "$user" "$path"
done < <(jq -cr '.[]' <<<"$backups_to_perform")
rsync_backup es solo una función para realizar la sincronización rsync que acepta esos argumentos.
Es posible que exista una solución mejor para lograr las copias de seguridad de lo que quiero, pero me gustaría mejorar este tipo de código para poder aplicarlo mejor la próxima vez.
Mi problema es que esto parece llevar mucho tiempo cuando el JSON es grande (he reducido a 3 para esta publicación). También parece que mi forma de analizar el JSON es muy complicada, pero no pude hacerla funcionar de ninguna otra manera.
Probablemente sea malo llamar a jq
una vez para alimentar el bucle y luego llamarlo nuevamente en cada iteración.
davy.ai
Como experto en TI especializado en arrays, JSON, bash, rendimiento y jq, sugeriría las siguientes mejoras para optimizar el código anterior:
jq
en cada iteración, parsea el JSON una vez y guárdalo en un array para poder iterar sobre él en el bucle. Esto reducirá el número de llamadas ajq
.for
en lugar de un buclewhile
para iterar sobre el array. esto es más eficiente que utilizar un buclewhile read
.rsync_backup
para que acepte los argumentos de backup como un array en lugar de variables individuales.con estas mejoras, el código debería ser más rápido y eficiente, incluso con una entrada json grande. [=”” {=”” “key”:=”” “key1″,=”” “user”:=”” “user1″,=”” “path”:=”” “path1″=”” },=”” {=”” “key”:=”” “key2″,=”” “user”:=”” “user2″,=”” “path”:=”” “path2″=”” },=”” {=”” “key”:=”” “key3″,=”” “user”:=”” “user3″,=”” “path”:=”” “path3″=”” }=”” ]=”” eof=”” )=”” backups=”($(echo” “${backups_to_perform}”=”” |=”” jq=”” -r=”” ‘.[]=”” |=”” [.key,=”” .user,=”” .path]=”” |=”” @sh’))=””
="" 2.="" utiliza="" un="" bucle="" `for`="" en="" lugar="" de="" un="" bucle="" `while`="" para="" iterar="" sobre="" el="" array.="" esto="" es="" más="" eficiente="" que="" utilizar="" un="" bucle="" `while="" read`.=""
sh=”” for=”” backup=”” in=”” “${backups[@]}”;=”” do=”” rsync_backup=”” “${backup}”=”” done=””="" 3.="" modifica="" la="" función="" `rsync_backup`="" para="" que="" acepte="" los="" argumentos="" de="" backup="" como="" un="" array="" en="" lugar="" de="" variables="" individuales.=""
sh=”” rsync_backup()=”” {=”” local=”” backup=”("$@")” local=”” key=”${backup[0]}” local=”” user=”${backup[1]}” local=”” path=”${backup[2]}” #=”” realiza=”” el=”” backup=”” usando=”” $key,=”” $user=”” y=”” $path=”” con=”” rsync=”” }=”” “`=”” con=”” estas=”” mejoras,=”” el=”” código=”” debería=”” ser=”” más=”” rápido=”” y=”” eficiente,=”” incluso=”” con=”” una=”” entrada=”” json=””></eof[
{
“key”: “key1”,
“user”: “user1”,
“path”: “path1”
},
{
“key”: “key2”,
“user”: “user2”,
“path”: “path2”
},
{
“key”: “key3”,
“user”: “user3”,
“path”: “path3”
}
]
eof
)
backups=($(echo “${backups_to_perform}” | jq -r ‘.[] | [.key, .user, .path] | @sh’))
rsync_backup
para que acepte los argumentos de backup como un array en lugar de variables individuales.con estas mejoras, el código debería ser más rápido y eficiente, incluso con una entrada json grande.>