ファイル名を変数に分割するには?

ファイル名を変数に分割するには?

次の形式のcsvファイルのリストがあるとします。

INT_V1_<Product>_<ID>_<Name>_<ddmmyy>.csv
ASG_B1_V1_<Product>_<ID>_<Name>_<ddmmyy>.csv

これINT_V1_&ASG_B1_V1_固定されています。つまり、すべてのcsvファイルはこの値で始まります。
ファイル名を変数に分割するには?
たとえば、キャプチャしたいと思います。名前&はそれを変数に割り当てます$Name

ベストアンサー1

そして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

bashzsh 4.3以上、ksh93t以上、またはshエミュレーションを使用すると(zshではSplit + globナンセンス演算子を使用するよりもzsh単純に分割する方が良いですが)、文字ごとに文字列を分割して最後に引用符から始めることができます。 :field=("${(@s:_:)field}")sh_

IFS=_
set -o noglob
field=($file) # split+glob  operator
date=${field[-1]%.*}
name=${field[-2]}
id=${field[-3]}
product=${field[-4]}

または(bash 3.2以降):

if [[ $file =~ .*_(.*)_(.*)_(.*)_(.*)\.csv$ ]]; then
  product=${BASH_REMATCH[1]}
  id=${BASH_REMATCH[2]}
  name=${BASH_REMATCH[3]}
  date=${BASH_REMATCH[4]}
fi

(これは$file現在のロケールに有効なテキストが含まれていると仮定しますが、ロケールをCまたは文字ごとに1バイトの文字セットを持つ別のロケールに変更しない限り、ファイル名が有効であることを保証することはできません。)

上記zshの通りです*.*貪欲。したがって、最初の項目はできるだけ多く食べるので、*_残りは一致がない文字列のみを.*一致します。_

それでksh93あなたはできます

pattern='*_(*)_(*)_(*)_(*).csv'
product=${file//$pattern/\1}
id=${file//$pattern/\2}
name=${file//$pattern/\3}
date=${file//$pattern/\4}

POSIXスクリプトでは、標準パラメータ拡張演算子をsh使用できます。${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##*_}

または、再度 Split+glob 演算子を使用してください。

IFS=_
set -o noglob
set -- $file
shift "$(($# - 4))"
product=$1 id=$2 name=$3 date=${4%.*}

おすすめ記事