web-dev-qa-db-fra.com

Utilisation de match pour rechercher des sous-chaînes dans des chaînes avec uniquement bash

Bien que je sois presque sûr que cela a été couvert, je ne trouve rien qui soit spécifique à cela. Alors que je poursuis mon cheminement en apprentissage, je continue de chercher des passages où je suis perplexe quant à la raison pour laquelle les choses se passent ainsi. 

Rechercher et remplacer ou simplement faire correspondre des sous-chaînes dans des chaînes est probablement l'une des premières choses que vous faites lorsque vous écrivez des scripts. Cependant, essayer de s'en tenir à une seule langue ou à un ensemble d'outils est difficile à faire pendant la session, car vous êtes capable de résoudre la plupart des problèmes de plusieurs façons. Je fais de mon mieux pour rester aussi bas que possible avec bash. J'ai rencontré un problème que j'ai besoin de quelqu'un pour m'expliquer. 

Faire une sous-chaîne avec une recherche dans bash avec correspondance me donne des résultats différents selon l'expression régulière que j'utilise, et je ne sais pas pourquoi. 

#!/bin/bash
Stext="Hallo World"
echo `expr "$Stext" : '^\(.[a-z]*\)'` # Hallo
echo `expr "$Stext" : '.*World'`      # 11

Bien que les deux recherchent un mot, je pense , les deux ne renvoient pas ce qu'ils ont trouvé. Pourquoi? 

39
Willem P. Botha

Les deux expressions sont équivalentes, la différence est l'expression régulière que vous utilisez:

$ echo `expr "$Stext" : '^\(.[a-z]*\)'`
Hallo
$ echo `expr "$Stext" : '^.[a-z]*'`
5
$ echo `expr "$Stext" : '\(.*World\)'`
Hallo World
$ echo `expr "$Stext" : '.*World'`
11

Comme vous pouvez le constater, ce sont les parenthèses qui permettent de renvoyer la longueur de la correspondance ou la correspondance elle-même.

Vous trouverez plus d'exemples dans Chapitre 10 du guide Advanced Bash-Scripting Guide.

27
jcollado

Vous pouvez utiliser la variable BASH_REMATCH dans bash pour obtenir la chaîne correspondante:

$ Stext="Hallo World"
$ [[ $Stext =~ ^.[a-z]* ]] && echo $BASH_REMATCH
Hallo
$ [[ $Stext =~ ^(.[a-z]*) ]] && echo ${BASH_REMATCH[1]}
Hallo

Les sous-chaînes mises en correspondance par des sous-expressions entre parenthèses dans l'expression régulière sont enregistrées dans la variable de tableau BASH_REMATCH . L'élément BASH_REMATCH avec l'index 0 est la partie de la chaîne correspondant à l'expression régulière entière. L'élément BASH_REMATCH d'index n est la partie de la chaîne correspondant à la nième sous-expression entre parenthèses. 

59
kev

J'ai créé cette fonction simple:

match() {
    TRUE=1
    FALSE=0
    match_return=0
    echo $1 | grep $2 >/dev/null
    [ $? -eq 0 ] && match_return=$TRUE || match_return=$FALSE
}

Usage:

match Testing Test ; [ $match_return -eq 1 ] && echo "match!" || echo "nope"

code entier: https://Gist.github.com/TeeBSD/5121b3711fad40a09455

0
Antonio Feitosa