web-dev-qa-db-ja.com

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

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

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

INT_V1 _ASG_B1_V1 _は修正されました。つまり、すべてのcsvファイルがそれで始まります。
ファイル名を変数に分割するにはどうすればよいですか?
たとえば、Nameをキャプチャして、変数$Nameに割り当てたいと思いました。

9
Juliet.Y

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
_

Shエミュレーションでのbash 4.3以降、ksh93t以降、またはzsh(zshでは、split + globを使用するのではなく、単に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の_*_と同様に、_.*_はgreedyです。したがって、最初のものはできる限り多くの_*__を食べるため、残りの_.*_は___フリーの文字列にのみ一致します。

_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%.*}
_
7

あなたはあなたのフィールドの値を取ることができます<Name>このコマンドを使用:

cut -d'<' -f4 < csvlist | sed -e 's/>_//g'

(またはawkを使用):

awk -F'<' '{print $4}' < csvlist | sed -e 's/>_//g'

そして、これらを次のような変数に入れることができます:

variable_name=$(cut -d'<' -f4 < csvlist | sed -e 's/>_//g')

または

awk -F'<' '{print $4}' < csvlist | sed -e 's/>_//g'

すべての値に同じ変数が必要か、値ごとに1つの変数が必要かは、質問では明確ではありません。

4
Zumo de Vidrio
file='INT_V1_<Product>_<ID>_<Name>_<ddmmyy>.csv'
IFS=\_ read -r x x product id name date x <<< "$file"
date=${date%.*}
1
user218374