com 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
Com bash
4.3 ou mais recente, ksh93t ou mais recente ou em emsh sh (embora em zsh
, você preferiria simplesmente fazer field=("${(@s:_:)field}")
para dividir do que usando o operador não-sentido split + glob de sh
) você pode dividir a string em _
caracteres e referenciá-los no final:
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 mais recente):
if [[ $file =~ .*_(.*)_(.*)_(.*)_(.*)\.csv$ ]]; then
product=${BASH_REMATCH[1]}
id=${BASH_REMATCH[2]}
name=${BASH_REMATCH[3]}
date=${BASH_REMATCH[4]}
fi
(que assume $file
contém texto válido no código do idioma atual que não é garantido para nomes de arquivos, a menos que você corrija o código de idioma para C ou outro código de idioma com um único byte por caractere charset).
Como zsh
' *
acima, o .*
é ganancioso . Assim, o primeiro vai comer o máximo de *_
possível, então o .*
restante corresponderá apenas a _
-free strings.
Com ksh93
, você poderia fazer
pattern='*_(*)_(*)_(*)_(*).csv'
product=${file//$pattern/}
id=${file//$pattern/}
name=${file//$pattern/}
date=${file//$pattern/}
Em um script POSIX sh
, você pode usar os operadores de expansão de parâmetro ${var#pattern}
, ${var%pattern}
:
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 use o operador split + glob novamente:
IFS=_
set -o noglob
set -- $file
shift "$(($# - 4))"
product=$1 id=$2 name=$3 date=${4%.*}