Bash에서 IFS를 2바이트 값으로 어떻게 설정합니까?
IFS=',;'
구분 기호는 구분 기호 대신 단순 및/또는 단순 두 ,
부분 사이에 있는 각 부분 입니까 ? 솔루션이 제공될 수 있도록 시뮬레이션/해결 방법을 수행하는 방법은 무엇입니까? 전에 고마워요;
,;
답변1
zsh
대신 ( plit용) 매개변수 확장 플래그를 bash
사용하여 전환할 수 있습니다 .s
s
$ string='foo,;bar,;,;baz'
$ words=("${(@s[,;])string}")
$ typeset -p words
typeset -a words=( foo bar '' baz )
이는나뉘다아니요정의하다는 IFS 분할(단일 문자만 포함)이 아닌 빈 문자열 foo,;
로 분할됩니다 .foo
foo
bash
또한 bash
(and zsh
, 모든 쉘은 아니지만)에서 분사는수치~의 $IFS
, 아니오바이트. 예를 들어, 를 사용하면 IFS='é'
2 바이트 로 인코딩된 로케일(예: 문자가 가장 일반적인 UTF-8로 매핑되는 로케일) 에서도 Stéphane
분할됩니다 .St
phane
é
답변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;d
5개의 필드가 있습니다. 해당 조합을 단일 구분 기호로만 사용하려면 ,;
수동으로 수행해야 합니다. 한 가지 방법은 ,;
쌍을 입력의 단일 문자로 바꾸는 것입니다 IFS
.
s='a,b,;c;d'
IFS=#
fields=(${s//,;/#})
${s//,;/#}
모든 하위 문자열을 ,;
다음으로 바꾼 #
다음 따옴표 없이 결과를 확장합니다. 이제 배열에는 sum 이 fields
포함됩니다 . 또한 생성된 단어를 glob(파일 이름 와일드카드)로 사용한다는 점에 유의하세요. 이를 방지하기 위해 / 를 사용하고 싶을 수도 있지만 에 할당되는 것 외에도 전역 효과도 있다는 점에 유의하세요.a,b
c;d
set -f
set -o noglob
IFS
sed
또는 특히 시작할 파이프라인이 있는 경우 다음을 사용할 수 있습니다 .
sed -e 's/,;/#/g'