web-dev-qa-db-fra.com

Script Bash - stocke la sortie `curl` dans la variable, puis la met en forme avec la chaîne dans la variable

J'espérais insérer des données curldans une variable de script shell, puis utiliser catou awkpour opérer sur cette variable comme s'il s'agissait d'un fichier.

Est-ce possible ou existe-t-il une solution de contournement? Dois-je enregistrer la commande curldans un fichier?

Dois-je exécuter curlplusieurs fois, pour chaque bit de formatage de chaîne que je souhaite effectuer?

Je suis curlname__ing ipinfo.io et je veux afficher les lignes correspondantes pour "ville" et "région". Je sais comment utiliser awket sedpour formater la sortie comme vous le souhaitez.

Essayez par exemple curl ipinfo.io/"8.8.8.8" pour obtenir le résultat d'une adresse IP DNS Google.

J'aimerais imprimer uniquement "Mountain View" et "California", de préférence sur la même ligne, avec un formatage courant, tel que "Mountain View, Californie".

7
cfye14

En général, il existe des méthodes plus appropriées d’analyse des objets JSON, mais comme l’objet JSON est très simple, vous pouvez stocker la sortie de curlname __ dans une variable (ce qui est possible) et utiliser simplement AWK:

var="$(curl ipinfo.io/"8.8.8.8" 2>/dev/null)"
<<<"$var" awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
% var="$(curl ipinfo.io/"8.8.8.8" 2>/dev/null)"
% <<<"$var" awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
Mountain View, California

Cependant, à moins que vous ne vouliez utiliser la sortie de curlname __ plusieurs fois, vous pouvez simplement utiliser un tube:

curl ipinfo.io/"8.8.8.8" 2>/dev/null | awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
curl ipinfo.io/"8.8.8.8" 2>/dev/null | awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
Mountain View, California

<<< est une forme de redirection d'entrée appelée "here string"; il redirige le STDIN d'une commande du terminal vers une chaîne.

Ce qui se passe ici est que $var est développé entre les guillemets doubles; le STDIN de la commande AWK est redirigé du terminal vers la chaîne développée et AWK lit par conséquent la chaîne en tant que fichier d'entrée.

8
kos

J'espérais intégrer des données dans une variable de script Shell, puis utiliser cat ou awk pour agir sur cette variable comme s'il s'agissait d'un fichier. Est-ce possible ou existe-t-il une solution de contournement?

Sûr que vous pouvez. Si le contenu n'est pas trop volumineux et si vous souhaitez exécuter plusieurs commandes pour analyser le contenu, il est préférable de le mettre en cache dans la mémoire plutôt que de le télécharger à nouveau à chaque fois.

Pour stocker le résultat de curl dans une variable:

ipinfo=$(curl ipinfo.io/8.8.8.8)

Pour exécuter des commandes dessus:

<<< "$ipinfo" awk ...
<<< "$ipinfo" sed ...

Les doubles guillemets no `" $ ipinfo "sont importants pour conserver tous les caractères d'espacement.

Une "solution de contournement" pour ne pas enregistrer le contenu dans une variable consiste à trouver un moyen de traiter le contenu dans un seul pipeline, comme @ kos l'a fait.

6
janos

Un autre moyen facile et plus lisible de faire cela, vous pouvez utiliser python, qui existe dans tous les systèmes Linux, pour analyser le json pour vous.

Importez simplement les packages json_ et sys pour charger l’objet json, puis imprimez à partir de l’objet result toute propriété dont vous avez besoin:

curl ipinfo.io/"8.8.8.8" 2>/dev/null | 
  python -c 'import  json,sys; 
             result=json.load(sys.stdin); 
             print(result["'city'"] + ", " + result["'region'"])';

J'ai ajouté le script de manière plus lisible, mais vous devez insérer une ligne ou ajouter \ à la fin de chaque ligne si vous devez l'écrire sur plusieurs lignes.

1
msoliman