파일 이름을 변수로 분할하는 방법은 무엇입니까?

파일 이름을 변수로 분할하는 방법은 무엇입니까?

다음 형식의 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%.*}

답변2

<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'

모든 값에 동일한 변수를 사용할 것인지, 아니면 각 값에 대해 하나의 변수를 사용할 것인지는 질문에서 명확하지 않습니다.

답변3

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

답변4

이와 같이

$ basename file.csv .csv 
file

관련 정보