Mit 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
Mit bash
4.3 oder neuer, ksh93t oder neuer oder zsh in der Sh-Emulation (obwohl zsh
Sie dies eher field=("${(@s:_:)field}")
zum Teilen tun als mit dem unsinnigen Operator split + glob von sh
) können Sie die Zeichenfolge auf _
Zeichen aufteilen und sie vom Ende aus referenzieren ::
IFS=_
set -o noglob
field=($file) # split+glob operator
date=${field[-1]%.*}
name=${field[-2]}
id=${field[-3]}
product=${field[-4]}
Oder (Bash 3.2 oder neuer):
if [[ $file =~ .*_(.*)_(.*)_(.*)_(.*)\.csv$ ]]; then
product=${BASH_REMATCH[1]}
id=${BASH_REMATCH[2]}
name=${BASH_REMATCH[3]}
date=${BASH_REMATCH[4]}
fi
(Dies setzt voraus, dass $file
das aktuelle Gebietsschema gültigen Text enthält, der für Dateinamen nur dann garantiert wird, wenn Sie das Gebietsschema auf C oder ein anderes Gebietsschema mit einem Einzelbyte-Zeichensatz pro Zeichen festlegen.)
Wie zsh
‚s *
oben, das .*
ist gierig . Der erste frisst also so viele *_
wie möglich, der Rest .*
passt nur zu _
freien Saiten.
Mit ksh93
könnte man machen
pattern='*_(*)_(*)_(*)_(*).csv'
product=${file//$pattern/\1}
id=${file//$pattern/\2}
name=${file//$pattern/\3}
date=${file//$pattern/\4}
In einem POSIX - sh
Skript, können Sie die verwenden ${var#pattern}
, ${var%pattern}
Standardparameter Expansion Operatoren:
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##*_}
Oder verwenden Sie den Operator split + glob erneut:
IFS=_
set -o noglob
set -- $file
shift "$(($# - 4))"
product=$1 id=$2 name=$3 date=${4%.*}