Bash에서 IFS를 2바이트 값으로 설정

Bash에서 IFS를 2바이트 값으로 설정

Bash에서 IFS를 2바이트 값으로 어떻게 설정합니까?

IFS=',;'

구분 기호는 구분 기호 대신 단순 및/또는 단순 두 ,부분 사이에 있는 각 부분 입니까 ? 솔루션이 제공될 수 있도록 시뮬레이션/해결 방법을 수행하는 방법은 무엇입니까? 전에 고마워요;,;

답변1

zsh대신 ( plit용) 매개변수 확장 플래그를 bash사용하여 전환할 수 있습니다 .ss

$ string='foo,;bar,;,;baz'
$ words=("${(@s[,;])string}")
$ typeset -p words
typeset -a words=( foo bar '' baz )

이는나뉘다아니요정의하다는 IFS 분할(단일 문자만 포함)이 아닌 빈 문자열 foo,;로 분할됩니다 .foofoobash

또한 bash(and zsh, 모든 쉘은 아니지만)에서 분사는수치~의 $IFS, 아니오바이트. 예를 들어, 를 사용하면 IFS='é'2 바이트 로 인코딩된 로케일(예: 문자가 가장 일반적인 UTF-8로 매핑되는 로케일) 에서도 Stéphane분할됩니다 .Stphaneé

답변2

bash(버전 4.3+) 기능:

split() {
    local string=$1 fs=$2
    local -n fields=$3
    fields=()
    while [[ $string =~ (.*)"$fs"(.*) ]]; do
        fields=( "${BASH_REMATCH[2]}" "${fields[@]}" )
        string=${BASH_REMATCH[1]}
    done
    fields=( "$string" "${fields[@]}" )
}

용법:

$ string="field1,;field2,field2b,;field3a;field3b,;,;field4"
$ split "$string" ",;" result
$ declare -p result
declare -a result=([0]="field1" [1]="field2,field2b" [2]="field3a;field3b" [3]="" [4]="field4")

구분 기호를 따옴표로 묶은 CSV 구문 분석을 구현하려는 많은 순진한 시도와 마찬가지로 실패합니다.

$ split 'Thoughtfully, he said "Hello, friend."' , x
$ declare -p x
declare -a x=([0]="Thoughtfully" [1]=" he said \"Hello" [2]=" friend.\"")

답변3

IFS은 단일 문자 구분 기호 집합이므로 , IFS=,;또는 ;모두 ,구분 기호로 사용되며 a,b,;c;d5개의 필드가 있습니다. 해당 조합을 단일 구분 기호로만 사용하려면 ,;수동으로 수행해야 합니다. 한 가지 방법은 ,;쌍을 입력의 단일 문자로 바꾸는 것입니다 IFS.

s='a,b,;c;d'
IFS=#
fields=(${s//,;/#})

${s//,;/#}모든 하위 문자열을 ,;다음으로 바꾼 #다음 따옴표 없이 결과를 확장합니다. 이제 배열에는 sum 이 fields포함됩니다 . 또한 생성된 단어를 glob(파일 이름 와일드카드)로 사용한다는 점에 유의하세요. 이를 방지하기 위해 / 를 사용하고 싶을 수도 있지만 에 할당되는 것 외에도 전역 효과도 있다는 점에 유의하세요.a,bc;dset -fset -o noglobIFS

sed또는 특히 시작할 파이프라인이 있는 경우 다음을 사용할 수 있습니다 .

sed -e 's/,;/#/g'

관련 정보