Si vous utilisez Bash, vous n'avez même pas besoin d'utiliser grep
:
files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*"
for f in $files # unquoted in order to allow the glob to expand
do
if [[ $f =~ $regex ]]
then
name="${BASH_REMATCH[1]}"
echo "${name}.jpg" # concatenate strings
name="${name}.jpg" # same thing stored in a variable
else
echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files
fi
done
Il est préférable de mettre l'expression régulière dans une variable. Certains modèles ne fonctionneront pas s'ils sont inclus littéralement.
Ceci utilise =~
qui est l'opérateur de correspondance d'expressions régulières de Bash. Les résultats de la correspondance sont enregistrés dans un tableau appelé $BASH_REMATCH
. Le premier groupe de capture est stocké dans l'index 1, le second (le cas échéant) dans l'index 2, etc. L'index zéro est la correspondance complète.
Vous devez savoir que sans ancrages, cette expression régulière (et celle qui utilise grep
) correspondra à l'un des exemples suivants et plus, ce qui peut ne pas être ce que vous recherchez:
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
Pour éliminer les deuxième et quatrième exemples, faites votre regex comme ceci:
^[0-9]+_([a-z]+)_[0-9a-z]*
qui dit que la chaîne doit commencer par un ou plusieurs chiffres. Le carat représente le début de la chaîne. Si vous ajoutez un signe dollar à la fin de l'expression régulière, comme ceci:
^[0-9]+_([a-z]+)_[0-9a-z]*$
alors le troisième exemple sera également éliminé car le point ne fait pas partie des caractères de l'expression régulière et le signe dollar représente la fin de la chaîne. Notez que le quatrième exemple échoue également cette correspondance.
Si vous avez GNU grep
(environ 2,5 ou plus tard, je pense, lorsque l' \K
opérateur a été ajouté):
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
L' \K
opérateur (recherche de longueur variable) entraîne la correspondance du modèle précédent, mais n'inclut pas la correspondance dans le résultat. L'équivalent de longueur fixe est (?<=)
- le motif serait inclus avant la parenthèse fermante. Vous devez utiliser \K
si quantificateurs peuvent correspondre à des chaînes de longueurs différentes (par exemple +
, *
, {2,4}
).
L' (?=)
opérateur correspond à des modèles de longueur fixe ou variable et est appelé "anticipation". Il n'inclut pas non plus la chaîne correspondante dans le résultat.
Afin de rendre la correspondance insensible à la casse, l' (?i)
opérateur est utilisé. Il affecte les motifs qui le suivent, sa position est donc significative.
Le regex peut avoir besoin d'être ajusté selon qu'il y a d'autres caractères dans le nom de fichier. Vous remarquerez que dans ce cas, je montre un exemple de concaténation d'une chaîne en même temps que la sous-chaîne est capturée.