web-dev-qa-db-fra.com

chaîne de correspondance regex bash

J'essaie d'écrire un script bash contenant une fonction. Ainsi, lorsqu'un fichier .tar, .tar.bz2, .tar.gz, etc. est utilisé, il utilise tar avec les commutateurs appropriés pour décompresser le fichier.

J'utilise if si Elif, puis des instructions qui testent le nom du fichier pour voir par quoi il se termine et je ne parviens pas à le faire correspondre à l'aide de métacaractères regex.

Pour sauvegarder en permanence la réécriture du script que j'utilise 'test' sur la ligne de commande, j'ai pensé que l'instruction ci-dessous devrait fonctionner. J'ai essayé toutes les combinaisons de crochets, de citations et de métacharateurs possibles, sans succès.

test sed-4.2.2.tar.bz2 = tar\.bz2$; echo $?
(this returns 1, false)

Je suis sûr que le problème est simple et j'ai regardé partout, mais je ne peux pas comprendre comment le faire. Est-ce que quelqu'un sait comment je peux faire ça?

123
user1587462

Pour faire correspondre les expressions rationnelles, vous devez utiliser l'opérateur =~.

Essaye ça:

[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched

Alternativement, vous pouvez utiliser des caractères génériques (au lieu de regex) avec l'opérateur ==:

[[ sed-4.2.2.tar.bz2 == *tar.bz2 ]] && echo matched

Si la portabilité n'est pas un problème, je vous recommande d'utiliser [[ au lieu de [ ou test car il est plus sûr et plus puissant. Voir Quelle est la différence entre test, [et [[? pour plus de détails.

205
dogbane

Je n'ai pas assez de représentants pour commenter ici, alors je soumets une nouvelle réponse pour améliorer la réponse de dogbane. Le point . dans l'expression rationnelle 

[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched 

correspondra à n’importe quel caractère, pas seulement le point littéral entre 'tar.bz2', par exemple

[[ sed-4.2.2.tar4bz2 =~ tar.bz2$ ]] && echo matched
[[ sed-4.2.2.tar§bz2 =~ tar.bz2$ ]] && echo matched

ou tout ce qui ne nécessite pas d'échapper avec '\' . La syntaxe stricte devrait alors être

[[ sed-4.2.2.tar.bz2 =~ tar\.bz2$ ]] && echo matched

ou vous pouvez aller encore plus strict et inclure également le point précédent dans la regex:

[[ sed-4.2.2.tar.bz2 =~ \.tar\.bz2$ ]] && echo matched
6
user2066480

Puisque vous utilisez bash, vous n'avez pas besoin de créer un processus enfant pour le faire. Voici une solution qui le réalise entièrement dans bash:

[[ $TEST =~ ^(.*):\ +(.*)$ ]] && TEST=${BASH_REMATCH[1]}:${BASH_REMATCH[2]}

Explanation: Les groupes avant et après la séquence "deux points et un ou plusieurs espaces" sont enregistrés par l'opérateur de correspondance de modèle dans le tableau BASH_REMATCH.

2
user1934428
if [[ $STR == *pattern* ]]
then
    echo "It is the string!"
else
    echo "It's not him!"
fi

Travaille pour moi! GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

0
juan cortez

shopt -s nocasematch

if [[ sed-4.2.2.$LINE =~ (yes|y)$ ]]
 then exit 0 
fi
0
Shyam Gupta