web-dev-qa-db-fra.com

Comment trouver une sous-chaîne dans une chaîne (ou comment grep une variable)?

J'utilise BASH et je ne sais pas comment trouver une sous-chaîne. Il continue d'échouer, j'ai une chaîne (faut-il un tableau?)

Ci-dessous, LIST est une liste de chaînes de noms de bases de données, SOURCE est la réponse, l'une de ces bases de données. Ce qui suit ne fonctionne toujours pas:

echo "******************************************************************"
echo "*                  DB2 Offline Backup Script                     *"
echo "******************************************************************"
echo "What's the name of of the  database you would like to backup?"
echo "It will be named one in this list:"
echo ""
LIST=`db2 list database directory | grep "Database alias" | awk '{print $4}'`
echo $LIST
echo ""
echo "******************************************************************"
echo -n ">>> "
read -e SOURCE

if expr match "$LIST" "$SOURCE"; then
    echo "match"
    exit -1
else
    echo "no match"
fi
exit -1

J'ai aussi essayé mais ça ne marche pas:

if [ `expr match "$LIST" '$SOURCE'` ]; then
25
edumike
LIST="some string with a substring you want to match"
SOURCE="substring"
if echo "$LIST" | grep -q "$SOURCE"; then
  echo "matched";
else
  echo "no match";
fi
47
dietbuddha

Vous pouvez également comparer avec des caractères génériques:

if [[ "$LIST" == *"$SOURCE"* ]]

27
sreimer

Si vous utilisez bash, vous pouvez simplement dire

if grep -q "$SOURCE" <<< "$LIST" ; then
    ...
fi
6
Sorpigal

Cela fonctionne dans Bash sans forking de commandes externes:

function has_substring() {
   [[ "$1" != "${2/$1/}" ]]
}

Exemple d'utilisation:

name="hello/world"
if has_substring "$name" "/"
then
   echo "Indeed, $name contains a slash!"
fi
5
Hisham H M
expr match "$LIST" '$SOURCE'

ne fonctionne pas à cause de cette fonction, recherchez $ SOURCE depuis le début de la chaîne et renvoie la position juste après le motif $ SOURCE si trouvé, sinon 0. Vous devez donc écrire un autre code:

expr match "$LIST" '.*'"$SOURCE" or expr "$LIST" : '.*'"$SOURCE"

L'expression $ SOURCE doit être citée en double afin qu'un analyseur puisse définir une substitution. Les guillemets simples ne se substituent pas et le code ci-dessus cherchera la chaîne textuelle $ SOURCE à partir du début de la liste $ LIST. Si vous avez besoin du début de la chaîne, soustrayez la longueur $ SOURCE, par exemple $ {# SOURCE} . Vous pouvez également écrire

expr "$LIST" : ".*\($SOURCE\)"

Cette fonction extrait simplement $ SOURCE de $ LIST et le renvoie. Vous aurez une autre chaîne vide. Mais ils ont un problème avec double double quote. Je ne sais pas comment résoudre ce problème sans utiliser la variable supplémentaire . C'est une solution légère. Donc, vous pouvez écrire en C. Il existe une fonction ready strstr .Ne pas utiliser expr index, c’est donc très attrayant. Mais indexer la recherche pas la sous-chaîne et seulement le premier caractère. 

1
Anatoly

Vous pouvez utiliser "index" si vous souhaitez rechercher un seul caractère, par exemple:

LIST="server1 server2 server3 server4 server5"
SOURCE="3"
if expr index "$LIST" "$SOURCE"; then
    echo "match"
    exit -1
else
    echo "no match"
fi

La sortie est:

23
match
1
Angelo Babudro

expr est utilisé au lieu de [plutôt qu'à l'intérieur, et les variables ne sont développées qu'à l'intérieur des guillemets doubles, alors essayez ceci:

if expr match "$LIST" "$SOURCE"; then

Mais je ne comprends pas vraiment ce que SOURCE est censé représenter.

Il semble que votre code lise un motif à partir d'une entrée standard et se ferme s'il correspond à un alias de base de données, sinon il affichera "ok" Est-ce que c'est ce que tu veux?

0
Mikel

Eh bien, qu'en est-il de quelque chose comme ça:

PS3="Select database or <Q> to quit: "
select DB in db1 db2 db3; do
   [ "${REPLY^*}" = 'Q' ] && break
   echo "Should backup $DB..."
done
0
Diego Torres Milano