Correspondance de modèle de chaîne avec = ~

Jai des problèmes pour comprendre la correspondance de modèle de chaîne avec = ~ in bash .

Jai écrit la fonction suivante ( ne vous inquiétez pas – cest juste une expérience dexpérimentation, pas une approche de sécurité avec md5sum):

md5 () { [[ "$(md5sum $1)" =~ $2* ]] && echo fine || echo baarr; } 

et la testé avec une entrée. Voici quelques références:

md5sum wp.laenderliste b1eb0d822e8d841249e3d68eeb3068d3 wp.laenderliste 

Il est inutilement difficile de comparer, si la source de la somme de contrôle ne contient pas déjà les deux blancs avec le nom de fichier. « s doù proviennent les observations, mais mon observation est plus intéressante que les nombreuses façons de résoudre ce problème:

Je définis une variable de contrôle et teste ma fonction avec des chaînes trop courtes mais correspondantes:

ok=b1eb0d822e8d841249e3d68eeb3068d3 for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i} ;done fine fine fine fine 

Cela « est attendu et très bien, puisque cest le but de la fonction, dignorer la non-concordance des » wp.laenderliste « manquants et donc des discordances encore plus longues .

Maintenant, si jajoute des éléments aléatoires, qui ne correspondent pas, jattends, bien sûr, des erreurs, et je les reçois:

for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i}GU ;done baarr baarr baarr baarr 

Comme prévu. Mais lorsquil ny a quun seul, dernier caractère incompatible , voyez ce qui se passe:

for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i}G ;done fine fine fine fine 

Est-ce moi, ne réalisant pas comment cela est censé fonctionner (sélectionner est cassé), ou y a-t-il vraiment une erreur hors-un-par-un dans la correspondance de modèle de bash?

Les incohérences au milieu de la chaîne sont importantes à partir du compte 1:

for i in 5 9 e ; do echo md5 wp.laenderliste ${ok//$i/_} ;done md5 wp.laenderliste b1eb0d822e8d841249e3d68eeb3068d3 md5 wp.laenderliste b1eb0d822e8d84124_e3d68eeb3068d3 md5 wp.laenderliste b1_b0d822_8d841249_3d68__b3068d3 for i in 5 9 e ; do md5 wp.laenderliste ${ok//$i/_} ;done fine baarr baarr 

La version bash:

bash -version GNU bash, Version 4.3.48(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2013 Free Software Foundation, Inc. Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html> 

Clause de non-responsabilité : md5sum nest utile que contre les erreurs involontaires, pas contre les attaques. Je nencourage pas à lutiliser.

Et cette question nest pas une recherche de meilleures solutions ou solutions de contournement. Il sagit de = ~ Opérateur, sil doit agir comme il le fait et si oui, pourquoi.

Réponse

=~ in ([[ ]]) est une correspondance de modèle dexpression régulière (ou plutôt, une recherche , voir ci-dessous ). Cest différent de = (ou ==) qui utilise les mêmes modèles que les caractères génériques de nom de fichier.

Dans en particulier, lastérisque dans les expressions régulières signifie « zéro ou une copie de lunité précédente », donc abc* signifie ab plus zéro ou plus c s.

Dans votre cas, lastérisque de fin rend le caractère final de largument de fonction facultatif. Dans votre dernier exemple, le modèle devient ...68d3G*, et comme G* correspond à la chaîne vide, il correspond à une chaîne comme ...68d3. Regexese pour » toute chaîne « est de .*, ou » nimporte quel caractère, nimporte quel nombre de fois « .

Notez que la correspondance dexpression régulière recherche une correspondance nimporte où dans la chaîne, elle ne le fait pas « Il nest pas nécessaire que ce soit la chaîne entière . Ainsi, le modèle cde se trouverait dans la chaîne abcdefgh.

Vous voudrez peut-être utiliser quelque chose comme ceci:

[[ "$(md5sum "$1")" = "$2 "* ]] && echo ok 

Nous navons pas vraiment besoin dune correspondance dexpression régulière ici, et puisque md5sum renvoie lespace de fin ( plus filename) de toute façon, nous pouvons lutiliser dans le modèle pour vérifier que nous correspondons au modèle complet. Donc, donner à la fonction un hachage tronqué ne correspondrait pas.

Commentaires

  • Oh, maintenant je me sens sale. Je travaille principalement avec sed, lorsque jutilise la correspondance de motifs. Là, bien sûr, je dois utiliser. * et le savoir. Dune manière ou dune autre, jai appris lidée manifestement erronée, que jai oublier le point dans le shell – que ‘ nest que le cas pour la correspondance de nom de fichier, non? Dans le cas où / esac, le point est également nécessaire? I ‘ Jai lair si stupide, maintenant!;)
  • @userunknown, case utilise les mêmes modèles que pour le nom de fichier correspond, donc * correspond à tout, et le point nest que le point. Je pense que =~ est à peu près le seul endroit dans le shell qui utilise des expressions rationnelles. (Ensuite, bien sûr, ksh / Zsh / Bash ont des globes étendus qui ont à peu près les mêmes fonctionnalités que les expressions rationnelles, mais avec une syntaxe différente. Il doit être explicitement activé dans Bash, cependant.)
  • On pourrait aussi faire [ "$(md5sum < "$1")" = "$2 -" ] pour supprimer la dépendance sur ksh / zsh / bash (et éviter les problèmes avec les fichiers dont le nom commence par -).
  • Ok, cest une bonne excuse. Donc, la mémoire approximative, cette correspondance de motif dans le shell est compliquée, était au moins juste. Maintenant je me sens beaucoup mieux. 🙂 Maintenant, jai essayé = $2.* et cela fonctionne aussi, mais  » $ 2  » * le ferait être meilleur.Mais ce n’était qu’une expérience, alors j’ai gagné ‘ à utiliser autre chose que l’expérience d’apprentissage.

Réponse

Je nutiliserais pas de regex ici, juste une comparaison de chaînes:

md5 () { sum=$(md5sum "$1" | awk "{print $1}") [[ $sum = "$2" ]] && echo fine || echo baarr; } 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *