chaîne de correspondance bash regex

J’essaie d’écrire un script bash qui contient une fonction, alors, lorsqu’on lui donne un .tar , .tar.bz2 , .tar.gz etc., il utilise tar avec les commutateurs appropriés pour décompresser le fichier.

J’utilise si elif alors des instructions qui testent le nom de fichier pour voir avec quoi il se termine et je ne peux pas le faire correspondre à l’aide de métacaractères regex.

Pour éviter de réécrire constamment le script, j’utilise “test” sur la ligne de commande, je pensais que la déclaration ci-dessous devrait fonctionner, j’ai essayé toutes les combinaisons de parenthèses, de guillemets et de métacaratères et cela échoue toujours.

 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 le faire?

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

Essaye ça:

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

Vous pouvez également utiliser des caractères génériques (au lieu de regexes) avec l’opérateur == :

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

Si la portabilité n’est pas une préoccupation, je recommande d’utiliser [[ au lieu de [ ou de test car il est plus sûr et plus puissant. Voir Quelle est la différence entre test, [et [[? pour plus de détails.

Une fonction à faire

 extract () { if [ -f $1 ] ; then case $1 in *.tar.bz2) tar xvjf $1 ;; *.tar.gz) tar xvzf $1 ;; *.bz2) bunzip2 $1 ;; *.rar) rar x $1 ;; *.gz) gunzip $1 ;; *.tar) tar xvf $1 ;; *.tbz2) tar xvjf $1 ;; *.tgz) tar xvzf $1 ;; *.zip) unzip $1 ;; *.Z) uncompress $1 ;; *.7z) 7z x $1 ;; *) echo "don't know '$1'..." ;; esac else echo "'$1' is not a valid file!" fi } 

Autre note

En réponse à Aquarius Power dans le commentaire ci-dessus, We need to store the regex on a var

La variable BASH_REMATCH est définie après la correspondance avec l’expression, et $ {BASH_REMATCH [n]} correspondra au nième groupe ${BASH_REMATCH[1]} = "compressed" entre parenthèses, c’est-à-dire dans le ${BASH_REMATCH[1]} = "compressed" et ${BASH_REMATCH[2]} = ".gz"

 if [[ "compressed.gz" =~ ^(.*)(\.[az]{1,5})$ ]]; then echo ${BASH_REMATCH[2]} ; else echo "Not proper format"; fi 

(Le regex ci-dessus n’est pas censé être valide pour la dénomination de fichiers et les extensions, mais cela fonctionne pour l’exemple)

Je n’ai pas assez de rep 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 au 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 de s’échapper avec ‘\’. La syntaxe ssortingcte devrait alors être

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

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

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

shopt -s nocasematch

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

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

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

Explication: Les groupes avant et après la séquence “deux points et un ou plusieurs espaces” sont stockés par l’opérateur de correspondance de modèle dans le tableau BASH_REMATCH.

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

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