Avec zsh
:
file='INT_V1_<Product>_<ID>_<Name>_<ddmmyy>.csv'
setopt extendedglob
if [[ $file = (#b)*_(*)_(*)_(*)_(*).csv ]]; then
product=$match[1] id=$match[2] name=$match[3] date=$match[4]
fi
Avec bash
4.3 ou plus récent, ksh93t ou plus récent ou zsh dans l'émulation sh (bien que dans zsh
, vous préférez tout simplement faire field=("${(@s:_:)field}")
pour le fractionnement plutôt que d'utiliser l'opérateur de non-sens split + glob de sh
), vous pouvez diviser la chaîne en _
caractères et les référencer depuis la fin :
IFS=_
set -o noglob
field=($file) # split+glob operator
date=${field[-1]%.*}
name=${field[-2]}
id=${field[-3]}
product=${field[-4]}
Ou (bash 3.2 ou plus récent):
if [[ $file =~ .*_(.*)_(.*)_(.*)_(.*)\.csv$ ]]; then
product=${BASH_REMATCH[1]}
id=${BASH_REMATCH[2]}
name=${BASH_REMATCH[3]}
date=${BASH_REMATCH[4]}
fi
(cela suppose qu'il $file
contient du texte valide dans les paramètres régionaux actuels, ce qui n'est pas garanti pour les noms de fichiers, sauf si vous fixez les paramètres régionaux à C ou à d'autres paramètres régionaux avec un seul octet par jeu de caractères).
Comme zsh
« est *
ci - dessus, l' .*
est avide . Ainsi, le premier en mangera autant *_
que possible, de sorte que le reste .*
ne correspondra qu'à des _
chaînes libres.
Avec ksh93
, tu pourrais faire
pattern='*_(*)_(*)_(*)_(*).csv'
product=${file//$pattern/\1}
id=${file//$pattern/\2}
name=${file//$pattern/\3}
date=${file//$pattern/\4}
Dans un POSIX sh
script, vous pouvez utiliser les ${var#pattern}
, ${var%pattern}
opérateurs d'extension de paramètres standard:
rest=${file%.*} # remove .csv suffix
date=${rest##*_} # remove everything on the left up to the rightmost _
rest=${rest%_*} # remove one _* from the right
name=${rest##*_}
rest=${rest%_*}
id=${rest##*_}
rest=${rest%_*}
product=${rest##*_}
Ou utilisez à nouveau l'opérateur split + glob:
IFS=_
set -o noglob
set -- $file
shift "$(($# - 4))"
product=$1 id=$2 name=$3 date=${4%.*}