Với 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
Với bash
4.3 hoặc mới hơn, ksh93t hoặc mới hơn hoặc zsh trong mô phỏng sh (mặc dù trong zsh
, bạn chỉ đơn giản là làm field=("${(@s:_:)field}")
để phân tách hơn là sử dụng toán tử vô nghĩa split + global sh
), bạn có thể tách chuỗi trên các _
ký tự và tham chiếu chúng từ cuối :
IFS=_
set -o noglob
field=($file) # split+glob operator
date=${field[-1]%.*}
name=${field[-2]}
id=${field[-3]}
product=${field[-4]}
Hoặc (bash 3.2 trở lên):
if [[ $file =~ .*_(.*)_(.*)_(.*)_(.*)\.csv$ ]]; then
product=${BASH_REMATCH[1]}
id=${BASH_REMATCH[2]}
name=${BASH_REMATCH[3]}
date=${BASH_REMATCH[4]}
fi
(giả định đó $file
chứa văn bản hợp lệ trong ngôn ngữ hiện tại không được bảo đảm cho tên tệp trừ khi bạn sửa miền địa phương thành C hoặc miền địa phương khác với bộ ký tự một byte cho mỗi ký tự).
Giống như zsh
là *
ở trên, .*
là tham lam . Vì vậy, người đầu tiên sẽ ăn càng nhiều *_
càng tốt, do đó, người còn lại .*
sẽ chỉ kết hợp các _
chuỗi không có kết quả .
Với ksh93
, bạn có thể làm
pattern='*_(*)_(*)_(*)_(*).csv'
product=${file//$pattern/\1}
id=${file//$pattern/\2}
name=${file//$pattern/\3}
date=${file//$pattern/\4}
Trong một POSIX sh
kịch bản, bạn có thể sử dụng ${var#pattern}
, ${var%pattern}
khai thác mở rộng tham số tiêu chuẩn:
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##*_}
Hoặc sử dụng lại toán tử split + global:
IFS=_
set -o noglob
set -- $file
shift "$(($# - 4))"
product=$1 id=$2 name=$3 date=${4%.*}