Quelle est la façon la plus efficace de grep pour deux choses complètement distinctes et d'affecter les valeurs à des variables distinctes?

8

CentOS 6.x

Je veux prendre la sortie de curl, grep pour deux chaînes complètement séparées et affecter leurs valeurs respectives en tant que variables. Quelle est la manière la plus efficace de procéder (sans écrire la sortie sur le disque)?

Normalement, je penserais à avoir un script avec quelque chose comme:

#!/usr/bin/env bash
foo1=$(curl https://domain.com/file.xml | grep string1)
foo2=$(curl https://domain.com/file.xml | grep string2)

Mais cela finit par prendre deux passes et est horriblement inefficace. Y a-t-il une meilleure façon? Espérons une solution qui implique moins de passes?

Mike B
la source

Réponses:

10

1. Grepping en 1 variable

Essaye ça:

foo1=$(curl https://domain.com/file.xml | grep -E "string1|string2")

Cela s'exécutera curl1 fois et grep pour les occurrences de string1ou string2.

2. Grepping en 2 variables

Si ce sont des variables différentes, changez légèrement de tactique. Capturez la sortie de curlet ensuite grep.

output=$(curl https://domain.com/file.xml)
foo1=$(echo "$output" | grep "string1")
foo2=$(echo "$output" | grep "string2")

3. Entrer dans un tableau

Vous pouvez également stocker les résultats dans un tableau au lieu de variables distinctes.

output=$(curl https://domain.com/file.xml)
readarray foo < <(echo "$output" | grep "string1|string2")

Celui-ci est un peu difficile à gérer si vos résultats de grep ne retournent pas de résultats, car les résultats de "string2" peuvent être le premier ou le deuxième élément du tableau, mais je le fournis ici juste comme une démonstration de l'approche.

4. Lecture dans vars de grep

Encore une autre méthode qui utilise la readcommande avec la substitution de processus ( <( ..cmd..)).

$ read -d"\n" foo1 foo2 \
   <(curl https://domain.com/file.xml | grep -E "string1|string2")

Cela peut à nouveau être délicat si la recherche de "chaîne1" ne renvoie rien, provoquant l'apparition de correspondances pour "chaîne2" $foo1. De plus, cette approche a tendance à être moins portable que la n ° 2 ou la n ° 3 ci-dessus.

slm
la source
Désolé! J'avais une faute de frappe. Les variables sont en fait différentes. :-( Le résumé est maintenant mis à jour.
Mike B
Vous voudrez peut-être noter que la substitution de processus que vous recommandez est loin d'être une option portable.
mikeserv
@mikeserv - merci pour les commentaires, mis à jour.
slm
3
read var1 var2 <<CURLSED
$(curl $url | sed -nr 's/(regx1)\|(regx2)/"\1"'"$IFS"'"\2"/p')
CURLSED

Sérieusement, mec, il y a comme un million de façons d'écorcher ce chat.

mikeserv
la source