배시 (bash 스크립트입니다 한 줄로 분할하려면 냥이라구 및 저장할 어레이에서는 싶다.
선.
Paris, France, Europe
이러한 권한이 싶다 배열에서 다음과 같습니다.
array[0] = Paris
array[1] = France
array[2] = Europe
IFS=', ' read -r -a array <<< "$string"
참고로, 이 경우 '$ 로 개별적으로 구분 문자를 취급할 수 있도록 IFS' 이 필드를 쉼표 (,) 또는 공간이 아닌 e0100042.log either 구분된 두 개의 문자를 사용할 수 있습니다. 흥미롭게도, t, 빈 칸 # 39 의 입력 전능하신분은 표시되어도 aren& 쉼표 공간 때문에 공간이 생성될 때 특별히 치료를 받았다.
개별 요소에 액세스하려면:
echo "${array[0]}"
반복할 요소:
for element in "${array[@]}"
do
echo "$element"
done
인덱스 및 값은 모두 얻을 수 있습니다.
for index in "${!array[@]}"
do
echo "$index ${array[index]}"
done
마지막 비유하사 유용한 같도다라고 Bash 어레이입니다 스파스. 즉, 요소를 추가하거나 삭제할 수 있습니다 다음 연속적이지 지수 요소가 있다.
unset "array[1]"
array[42]=Earth
Afaq 요소의 수를 어레이에서는:
echo "${#array[@]}"
위에서 설명한 것처럼 사용할 수 있도록 # 39, t, 어레이에는 스파스 shouldn& afaq 디스테이징하는 마지막 요소. # 39 의 here& 수 있는 방법을 bash 4.2 이상:
echo "${array[-1]}"
어떤 버전의 배시 (후에 곳에서 2.05b):
echo "${array[@]: -1:1}"
더 큰 제외어 offsets 선택 끝에서 어레이입니다. 전 공간 기록하십시오 마이너스 로그인하십시오 이전 양식. 이 필요합니다.
[ 틀린 답을 # 1] (https://stackoverflow.com/a/10586169/4272464)
IFS=', ' read -r -a array <<< "$string"
이는 '$ IFS 1: 남용'. '안' $ 가치에 따라 수행한 단일 IFS 가변입니다 가변 길이 아닌 단일 문자 설정되었습니다 따라 수행한 것은 분리자의 문자열을 string that '읽기' 의 구분, 각 필드는 분할합니다 떨어져 있는 이 모든 로 문자 집합 내의 입력선의 해지할 수 있다 (쉼표 net/ 또는 공간, 예제에서와). 사실, 실제 사용 거기에, 전체 제꿈의 완고했다 '$ IFS)' 가 조금 더 있었다. [Bash 수작업식] 에서 (https://www.gnu.org/software/bash/manual/html_node/Word-Splitting.html # 단어 분할): >. , IFS 셸) 에서는 각 캐릭터는 구분 기호로 문자를 사용하여 다른 결과를 통해 이러한 확장 및 분할합니다 단어들은요 필드이므로 종료자에서. 설정하지 않은 경우, 또는 그 값은 정확히 &, lt, IFS, gt, gt, lt,, lt, tab& space& & & newline&, gt, gt, , space& & 시퀀스, 기본값입니다 관심용, lt, lt;;;; 및 &, lt, tab& &, gt, gt, newline& 시작과 끝에 결과를 무시됨 이전 확장 및 모든 일련의 , 는 IFS 아닌 문자가 시작 부분이나 끝 부분에 구분하는 것이다. IFS) 의 값을 갖는 경우, 다음, lt, 공백 문자가 아닌 기본값입니다 시퀀스에만 & space&, gt, gt, , , & tab& lt;;; gt, , lt, 및 & newline& 무시됨 시작과 끝에 word, deltamove 의 공백 문자 () 은 IFS ( 공백 문자 한 IFS) 의 값 . IFS 내 문자 없는 공백 문자를 IFS , 모든 공백을 IFS 함께 인접한 필드를 구분합니다. 공백 문자를 취급을 일련의 IFS) 도 구분. , IFS) 의 값이 널임 아무 말도 분할 발생합니다. 기본적으로 기본값과 다른 값이 null 이 아닌 '의' $ IFS (1) 로 구분할 수 있습니다, 필드 시퀀스일 문자 세트를 모두 " IFS) 에서 하나 이상의 공백 characters"; (즉, 중 어느 &, lt, space&, gt, , &, lt, tab&, gt, , , gt, lt, 및 & newline& (" newline"; 마무리라뇨 [라인 피드 (LF)] (https://en.wikipedia.org/wiki/Newline)) '에서' $ networkr. 어디든요 IFS) 또는 (2) 모든 non-" IFS 공백 character"; # 39 의 that& 함께 존재하는 '공백' $ IFS 있는모든 " IFS characters"; 이 부어지리니 입력선의.
IFS=', ' read -ra a <<<'Los Angeles, United States, North America'; declare -p a;
## declare -a a=([0]="Los" [1]="Angeles" [2]="United" [3]="States" [4]="North" [5]="America")
이 솔루션은 단일 문자 분리자를 2: 조교하실 경우에도 사용할 수 있는 (예, 즉, 다음과 같은 공간 없이 단독으로 쉼표 (,) 또는 기타 수하물) '$ 문자열을 변수 값을 포함할 경우' 에서 '읽기' 가 정지점을 변화가 발생합니까 LFs 관심용 처리 후 첫 번째 LF. 이 '읽기' 내장 프로세스만 한 줄에 한 호출. 만 경우에도 마찬가지입니다 파이핑을 '읽기' 를 입력 또는 리디렉션하는 기술서임을 예제에서와 사업을 진행하고 있는 것처럼 [여기 구체화하십시오] (https://www.gnu.org/software/bash/manual/html_node/Redirections.html # 여기 문장열) 메커니즘, 처리되지 않은 입력 및 카타시안 손실됩니다 장점이 있다. 이 코드는 '읽기' 를 더욱 강화하는 것을 포함하는 데이터 흐름 안에서 주님으로부터그에게 내장 명령 구조. 이 문제가 발생할 수 있는 가능성은 거의 없다고 주장할 수 있습니다, 그래도 it& # 39 의 미묘한 있는 위험을 가능하면 피해야 합니다. 이 사실은 '읽기' 내장 실제로 인한 두 가지 수준의 입력입니다 분할. 를 통해 첫 선을 관심용 보다 작은 자연수이다. 이후 이 사용에 대해 '읽기' 만 하고, 한 단계 나눠 OP 내장 적합하지 않을 수 있으며, 이를 피해야 한다. 이 솔루션을 통해 비 명백한 3: 잠재적인 문제가 있는 것은 '읽기' 비어 있는 경우에는 그렇지 않으면 비록 빈 칸을 떨어트림 뒤에 필드이므로 항상 유지합니다. # 39 의 here& 데모:
string=', , a, , b, c, , , '; IFS=', ' read -ra a <<<"$string"; declare -p a;
## declare -a a=([0]="" [1]="" [2]="a" [3]="" [4]="b" [5]="c" [6]="" [7]="")
[ 틀린 답을 # 2] (https://stackoverflow.com/a/15400047/4272464)
string="1:2:3:4:5"
set -f # avoid globbing (expansion of *).
array=(${string//:/ })
[비슷한 아이디어를:] (https://stackoverflow.com/a/31405855/4272464)
t="one,two,three"
a=($(echo $t | tr ',' "\n"))
(참고: 내가 추가했어야 누각되었습니다 괄호로 묶인 명령이 있는 것으로 대체 답변자 생략된다.) [비슷한 아이디어를:] (https://stackoverflow.com/a/37618160/4272464)
string="1,2,3,4"
array=(`echo $string | sed 's/,/\n/g'`)
[ 틀린 답을 # 3] (https://stackoverflow.com/a/39474755/4272464)
str="a, b, c, d" # assuming there is a space after ',' as in Q
arr=(${str//,/}) # delete all occurrences of ','
[ 틀린 답을 # 4] (https://stackoverflow.com/a/13196466/4272464)
string='first line
second line
third line'
oldIFS="$IFS"
IFS='
'
IFS=${IFS:0:1} # this is useful to format your code with tabs
lines=( $string )
IFS="$oldIFS"
[ # 틀린 답을 5] (https://stackoverflow.com/a/41225957/4272464)
countries='Paris, France, Europe'
OIFS="$IFS"
IFS=', ' array=($countries)
IFS="$OIFS"
[비슷한 아이디어를:] (https://stackoverflow.com/a/30744597/4272464)
IFS=', ' eval 'array=($string)'
이 솔루션은 상호 간에 효과적으로 # # 1 (쉼표 공간 점에서 세트 '를' $ ifs) 와 2-4 (점에서 문자열을 사용하는 단어 분할 분할하려면 필드에). 이 때문에 이 문제는 대부분 위의 모든 잘못된 답을 시달리고, 아니, 일종의 같은 최악의 상황은 모든 장점을. 또한 두 번째 변형, '평가' 등 관련 것처럼 보일 수도 있습니다 호츨 완전히 불필요한 이래 인수가 단일 인용 구체화하십시오 ipv6-literal. 때문에 정적으로 알려져 있다. 하지만, 실제로 사용하는 '평가' s # 39 there& 매우 비 명백한 급여금 이런 식으로. 일반적으로 간단한 명령을 실행할 때 , 전용 가변적입니다 할당에서는 등으로 구성된 이 단어를 사용하지 않고 실제 명령 셸에서는 할당에서는 마무리라뇨 다음과 같은 환경에 영향을 미칩니다.
IFS=', '; ## changes $IFS in the shell environment
이 간단한 명령을 部门从 변수값 지정 여러 경우에도 마찬가지입니다. # 39 라는 명령을 다시 deltamove there&, 모든 변수값 지정 환경에 영향을 미치는 쉘로 게 전혀 없다.
IFS=', ' array=($countries); ## changes both $IFS and $array in the shell environment
하지만, 만약 가변으로 할당에서는 명령 이름을 첨부됩니다 (I like to call 이 assignment" 접두어입니다 ";) 영향을 주지 않는 대신 어졌다면 않니다 쉘로 환경 및 환경에 영향을 미치는 디렉토리에만 실행됨을 명령을 모두인지 상관 없이 기본 제공 또는 외부:
IFS=', ' :; ## : is a builtin command, the $IFS assignment does not outlive it
IFS=', ' env; ## env is an external command, the $IFS assignment does not outlive it
[Bash 수작업식] 에서 관련 쿼트에 (https://www.gnu.org/software/bash/manual/html_node/Simple-Command-Expansion.html # 간단한 명령을 개확장): >. 명령 이름 없는 경우 현재 쉘로 결과, 변수값 지정 영향을 줄 수 있습니다. 그렇지 않으면 com/go/4e6b330a_kr 가속화합니다 실행된 명령의 벤자민에 현재 쉘로 환경에 대한 영향을 줄 수 있습니다. 이 기능을 활용할 수 있다 ',' 피할 수 있게 하는 변경하십시오 변수 $ IFS 할당되었는지 일시적으로만 저장 및 복원 갬빗 등 모든 것을 '의 변수 $ 로이프스 진행되고 있는' 첫 변형. 그러나 우리가 직면하고 있는 문제는 슬라이드에서는 명령을 실행할 수 있는 사안 자체가 변수 할당 및 업그레이드됨 해야 할 일이 아니다 '라는 명령을 할 수 있는' $ IFS 할당에서는 임시. 같아 교도관님도요, 뭐 왜안돼요 추가하기만 op 없습니다. 명령을 할 수 있습니다 한 말은 이 같은 발언은 [': 내장 '] (https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html # 본 셸 기본 제공) 할 수 있는' $ ifs '할당에서는 임시? 그런 다음 동작하지 않을 수 있기 때문에 '임시' $ 어레이입니다 할당에서는 잘 알려져 있다.
IFS=', ' array=($countries) :; ## fails; new $array value never escapes the : command
따라서, re 효과적으로 we& # 39 의 가격으로 난국을 다소 캐치-22. 그러나 '평가' 는 코드가 실행될 때, 이 쉘로 환경, 마치 일반, 정적임 소스 코드를 실행할 수 있는 '' 평가 '및' $ 어레이입니다 할당에서는 그리하매 하나님이 안에 있는 동안 인수 할꺼이나 적용하십시오 쉘로 환경, 즉 '평가' 명령 '$ 접두어입니다 할당에서는 IFS' 이 '평가' 함장님이요 오래 접두사에 대한 않습니다. 이 두 번째 해트트릭을 기록하는 것과 이 솔루션을 사용하고 있는 것이다.
IFS=', ' eval 'array=($string)'; ## $IFS does not outlive the eval command, but $array does
[ # 틀린 답을 6] (https://stackoverflow.com/a/35789043/4272464)
IFS=', '; array=(Paris, France, Europe)
IFS=' ';declare -a array=(Paris France Europe)
[ 틀린 답을 # 7] (https://stackoverflow.com/a/31620022/4272464)
string='first line
second line
third line'
while read -r line; do lines+=("$line"); done <<<"$string"
이것은 가장 좋은 솔루션뀉뀉뀉뀉. # 39, 다시 사용하기 '읽기' re we& 것을 알 수 있습니다. 내가 말하는 '읽기' 적합하지 않았기 때문에, 이전에 didn& t # 39 는 두 가지 수준의 분할 때 서브네트워크에 번호요? 이 전략은 슬라이드에서는 읽을 수 있는 '콜' 방식으로 사실상 당 대표로 있을 뿐, 특히 1 단계 분할하여 끄기도구 필드 하나만 있는 호출 수준 있는 루프지 반복적으로 비용이 필요 call it # 39 it& 조금 있지만, s 는 재빠른 손은 작동하잖아. 수축됐는데 문제. 첫 번째: , 이름 하나 이상 제공할 경우 자동으로 급지될 인수 '읽기' 는 각 분야에서 분할됩니다 떨어져 있는 앞뒤의 공백 문자 입력 구체화하십시오. 이런 '$ IFS' 설정되었습니다 표시할지를 기본값으로 방관하겠나 앞서 설명한 것처럼, OP, 현재 이 게시물에 대해 이 있으며, 실제로 그의 신경을 쓰지 않을 수 있으며, 특정 용도 바람직한 구문 분석 기능을 비헤이비어를. 그러나 who wants to 구문 분석 할 이 필드에 문자열으로 모두가 만족하는 것은 아니다. 해결책은 있다, 그러나: '읽기' 는 다소 비 명백한 제로 이름을 인수만 전달하는 데 사용할 수 있습니다. 이 경우 '읽기' 를 저장할 수 있는 전체 입력선의 it gets 입력 스트림 변수에 이름이 ',', 그리고 보너스로 않니다 , $ 회신과 없는 스트립 앞뒤의 공백 &solarisdvd 값입니다. 이것은 매우 강력한 활용할 수 있는 '읽기' I& # 39, ve 셸 프로그래밍에서 자주 내 눈길을 끌고 있다. # 39 의 차이는 here& 시위를 비헤이비어를:
string=$' a b \n c d \n e f '; ## input string
a=(); while read -r line; do a+=("$line"); done <<<"$string"; declare -p a;
## declare -a a=([0]="a b" [1]="c d" [2]="e f") ## read trimmed surrounding whitespace
a=(); while read -r; do a+=("$REPLY"); done <<<"$string"; declare -p a;
## declare -a a=([0]=" a b " [1]=" c d " [2]=" e f ") ## no trimming
이 솔루션은 실제로 두 번째 문제를 해결할 수 없는 경우 같은 사용자 정의 필드 분리자를 OP& # 39 의 쉼표 공간. 전과 같이 멀티커랙터 구분, 이는 이 솔루션의 불행한 제한은라이센스 지원되지 않습니다. 우리는 적어도 분할되었습니다 수도 있지만, - d 옵션을 지정하여 '쉼표' 에 대한 분리자의 여바바 어떻게 됩니까.
string='Paris, France, Europe';
a=(); while read -rd,; do a+=("$REPLY"); done <<<"$string"; declare -p a;
## declare -a a=([0]="Paris" [1]=" France")
이 때문에, 이 공백을 attaboy 필드에 값이 당연히 분분했다 않은 주변 모습을 통해 이후에 있을 것이라고 교정됨 트림하기 작업 (직접 수행됨 while 루프 이 될 수도 있습니다). 그러나 there& # 39 의 또 다른 명백하네 오류: 유럽 누락되었습니다.! 대체 무슨일예요? 그 답은 '읽기' 실패한 경우 안타 되돌려줍니다 반환 코드 파일 끝 (이 경우 우리는 구체화하십시오 끝 연락할 수 있는 정보기술 (it) 의 마지막 터미네이터입니다 생길 없이 최종 필드 (field. 이로 인해 while 루프 손실됩니다 분할하려면 중간에 하나님은 최종 필드. 기술적으로 이 같은 오류가 아니라 이전 참조용이므로 맛보게. 필드 seperator 찍을 수 있는 것은 차이가 있을 때 기본값입니다 don& # 39, LF, 옵션, ',' t '-d 대체하십시오 < < <;' (" here-string";) 방금 전에 이를 수 있는 메커니즘을 LF 자동으로 첨부됩니다 문자열이어야 급지됩니다 대한 입력입니다 명령. 따라서 이 경우, 우리는 일종의 ) 를 통해 문제를 해결할 것을 알지 떨어트림 마지막 필드는 추가로 더미 종단기 다운스트림에서 입력입니다. # 39 의 솔루션, 이것이 바로 let& " dummy-terminator". 솔루션. We can it 솔루션 연결하여 수동으로 입력 문자열 더미 종단기 적용하십시오 집하여 우리 it 에 대한 사용자 정의 문자를 인스턴스화하며 때 여기 구체화하십시오:
a=(); while read -rd,; do a+=("$REPLY"); done <<<"$string,"; declare -p a;
declare -a a=([0]="Paris" [1]=" France" [2]=" Europe")
이런 문제는 해결되었다. 또 다른 방법은 while 루프 모두 '읽기' 만 있을 경우 (1) 과 (2) ',' 실패 '$ 회신과 반환되었습니다 비워집니다 마무리라뇨 읽기 전에 모든 문자를 읽을 수 없는 타격' 는 파일 끝. 데모:
a=(); while read -rd,|| [[ -n "$REPLY" ]]; do a+=("$REPLY"); done <<<"$string"; declare -p a;
## declare -a a=([0]="Paris" [1]=" France" [2]=$' Europe\n')
[ # 틀린 답을 8] (https://stackoverflow.com/a/31620022/4272464)
string='first line
second line
third line'
readarray -t lines <<<"$string"
정답은
string='Paris, France, Europe';
readarray -td, a <<<"$string"; declare -p a;
## declare -a a=([0]="Paris" [1]=" France" [2]=$' Europe\n')
그 결과, 우리는 우리가 지켜보리니 잡을라는데 두 조건 읽기 '의' 에서 동일한 결과를 설명한 # 외곽진입 루프을 솔루션이므로 7. 우리는 이 문제를 해결할 수 있는 거의 수작업식 더미 종단기 트릭.
readarray -td, a <<<"$string,"; declare -p a;
## declare -a a=([0]="Paris" [1]=" France" [2]=" Europe" [3]=$'\n')
문제는 그 뒤에 ',', '리다레이 슬라이드에서는 아니했으니 필드이므로 < <, 이후,' 이 붙어 있기 때문에 문자열 입력을 위해 작동자 리디렉션을 < LF 는 뒤에 필드이므로 없는 빈 (그렇지 않으면 would& # 39, ve been 떨어트림). 이 마지막 배열 요소의 사후 의해 명시적으로 반환하기 잘있게나 수 있습니다.
readarray -td, a <<<"$string,"; unset 'a[-1]'; declare -p a;
## declare -a a=([0]="Paris" [1]=" France" [2]=" Europe")
남아 있는 유일한 두 가지 문제가 있으며, 실제로 관련 있다 (1) 외부 공백을 트림되지 하는 멀티커랙터 대한 지원 부족 및 (2) 를 구분. 물론 그 이후의 트리밍됩니다 (예를 들어, 볼 수 있는 공백 (https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable). 우리는 모두 해킹할 수 있는 문제를 해결할 것이라고 신앙이니라 멀티커랙터 구분, 그 한 샷. , 방법은 직접 멀티커랙터 죄송합니다. there& # 39 의 구분 없는 것이다. # 39 는 입력 문자열, ve 생각할 수 있는 최적의 솔루션을 I& 프레프록스 재장착하려면 멀티커랙터 구분 할 수 없는 보장할 수 있는 단일 문자 입력 내용을 충돌하고 구분 구체화하십시오. 이 문자 있는 유일한 작성하더라도 은 [NUL 바이트입니다] (https://en.wikipedia.org/wiki/Null_character). 이 때문에, bash (츠시 있는 것은 아니지만, 우여곡절 끝에), 변수를 사용할 수 없습니다 NUL 바이트입니다. 이 과정에서 전처리 단계에서 인라인 대체 할 수 있습니다. # 39 을 사용하여 here& 어떻게 해야 [awk] (https://www.gnu.org/software/gawk/):
readarray -td '' a < <(awk '{ gsub(/, /,"\0"); print; }' <<<"$string, "); unset 'a[-1]';
declare -p a;
## declare -a a=([0]="Paris" [1]="France" [2]="Europe")
function mfcb { local val="$4"; "$1"; eval "$2[$3]=\$val;"; };
function val_ltrim { if [[ "$val" =~ ^[[:space:]]+ ]]; then val="${val:${#BASH_REMATCH[0]}}"; fi; };
function val_rtrim { if [[ "$val" =~ [[:space:]]+$ ]]; then val="${val:0:${#val}-${#BASH_REMATCH[0]}}"; fi; };
function val_trim { val_ltrim; val_rtrim; };
readarray -c1 -C 'mfcb val_trim a' -td, <<<"$string,"; unset 'a[-1]'; declare -p a;
## declare -a a=([0]="Paris" [1]="France" [2]="Europe")
이것은 설정하지 않고 운행에서어떠한 IFS:
string="1:2:3:4:5"
set -f # avoid globbing (expansion of *).
array=(${string//:/ })
for i in "${!array[@]}"
do
echo "$i=>${array[i]}"
done
이 아이디어는 flexlm*용 구체화하십시오 교체품:
${string//substring/replacement}
달러 대신 공백 후 하위 일치시킵니다 교체할 수 있는 모든 문자열을 사용하여 초기화하려면 어레이입니다:
(element1 element2 ... elementN)
참고: 이 질문에 대한 사용 [split+glob 작동자] (https://unix.stackexchange.com/q/108963/79743). 따라서 확대를 막기 위해 일부 문자 ('*' 등) 이 스크립트입니다 글 로빙 일시정지하려면 것이 좋습니다.
가끔 발생했습니까 다는일은 해당 방법이 나와 수락됨 오토메이티드 # 39 는 return.<, 마차, 특히, t 작동합니까 didn& 분리자의 경우 br>. 이러한 경우는 내가 이 방법으로 해결했다.
string='first line
second line
third line'
oldIFS="$IFS"
IFS='
'
IFS=${IFS:0:1} # this is useful to format your code with tabs
lines=( $string )
IFS="$oldIFS"
for line in "${lines[@]}"
do
echo "--> $line"
done
이 값에 대해 대답을 한 line.< 수락됨 작동됨 br>; 여러 개의 변수를 경우 선:
string='first line
second line
third line'
모든 줄이 매우 다른 명령을 afaq 필요하다.
'읽을 때 boot-r 선. 책임질래 lines+ = ($ line" ";). ,, $ string" < 수행됨 < < ". '
또는 훨씬 간단해진다는 bash 리다레이 :
readarray -t lines <<<"$string"
Printf 의 모든 기능을 활용하여 인쇄면이 흐름선 매우 간단합니다.
printf ">[%s]\n" "${lines[@]}"
>[first line]
>[ second line]
>[ third line]
구분 문자 배열로 있다 '는 분할 다중 사용자 키를 문자열이어야 " ";'. 구분 문자 잘못 사용하여 멀티미디어 솔루션 'if' 모든 집합이 아니라 본질적으로 IFS 이후 이들 문자를 구체화하십시오.
할당할 경우, 그 중 하나에 끊어집니다. ',' IFS = " " 문자열이어야 ',' 또는 '" " "; 그 정확한 표현이 없는 조합을 ", '또는', '의 두 문자를 구분, " ".
Sed, awk 분할하려면 함께 사용할 수 있습니다 '' 또는 '' 문자열 처리 대체.
#!/bin/bash
str="Paris, France, Europe"
array=()
while read -r -d $'\0' each; do # use a NUL terminated field separator
array+=("$each")
done < <(printf "%s" "$str" | awk '{ gsub(/,[ ]+|$/,"\0"); print }')
declare -p array
# declare -a array=([0]="Paris" [1]="France" [2]="Europe") output
Regex 는 사용자가 직접 bash 보다 효율적으로 사용할 수 있다.
#!/bin/bash
str="Paris, France, Europe"
array=()
while [[ $str =~ ([^,]+)(,[ ]+|$) ]]; do
array+=("${BASH_REMATCH[1]}") # capture the field
i=${#BASH_REMATCH} # length of field + delimiter
str=${str:i} # advance the string by that length
done # the loop deletes $str, so make a copy if needed
declare -p array
# declare -a array=([0]="Paris" [1]="France" [2]="Europe") output...
두 번째 양식을 가진 것 없는 서브노드 쉘로 본질적으로 가속화합니다.
## competitors
function c_readarray { readarray -td '' a < <(awk '{ gsub(/, /,"\0"); print; };' <<<"$1, "); unset 'a[-1]'; };
function c_read { a=(); local REPLY=''; while read -r -d ''; do a+=("$REPLY"); done < <(awk '{ gsub(/, /,"\0"); print; };' <<<"$1, "); };
function c_regex { a=(); local s="$1, "; while [[ $s =~ ([^,]+),\ ]]; do a+=("${BASH_REMATCH[1]}"); s=${s:${#BASH_REMATCH}}; done; };
## helper functions
function rep {
local -i i=-1;
for ((i = 0; i<$1; ++i)); do
printf %s "$2";
done;
}; ## end rep()
function testAll {
local funcs=();
local args=();
local func='';
local -i rc=-1;
while [[ "$1" != ':' ]]; do
func="$1";
if [[ ! "$func" =~ ^[_a-zA-Z][_a-zA-Z0-9]*$ ]]; then
echo "bad function name: $func" >&2;
return 2;
fi;
funcs+=("$func");
shift;
done;
shift;
args=("$@");
for func in "${funcs[@]}"; do
echo -n "$func ";
{ time $func "${args[@]}" >/dev/null 2>&1; } 2>&1| tr '\n' '/';
rc=${PIPESTATUS[0]}; if [[ $rc -ne 0 ]]; then echo "[$rc]"; else echo; fi;
done| column -ts/;
}; ## end testAll()
function makeStringToSplit {
local -i n=$1; ## number of fields
if [[ $n -lt 0 ]]; then echo "bad field count: $n" >&2; return 2; fi;
if [[ $n -eq 0 ]]; then
echo;
elif [[ $n -eq 1 ]]; then
echo 'first field';
elif [[ "$n" -eq 2 ]]; then
echo 'first field, last field';
else
echo "first field, $(rep $[$1-2] 'mid field, ')last field";
fi;
}; ## end makeStringToSplit()
function testAll_splitIntoArray {
local -i n=$1; ## number of fields in input string
local s='';
echo "===== $n field$(if [[ $n -ne 1 ]]; then echo 's'; fi;) =====";
s="$(makeStringToSplit "$n")";
testAll c_readarray c_read c_regex : "$s";
}; ## end testAll_splitIntoArray()
## results
testAll_splitIntoArray 1;
## ===== 1 field =====
## c_readarray real 0m0.067s user 0m0.000s sys 0m0.000s
## c_read real 0m0.064s user 0m0.000s sys 0m0.000s
## c_regex real 0m0.000s user 0m0.000s sys 0m0.000s
##
testAll_splitIntoArray 10;
## ===== 10 fields =====
## c_readarray real 0m0.067s user 0m0.000s sys 0m0.000s
## c_read real 0m0.064s user 0m0.000s sys 0m0.000s
## c_regex real 0m0.001s user 0m0.000s sys 0m0.000s
##
testAll_splitIntoArray 100;
## ===== 100 fields =====
## c_readarray real 0m0.069s user 0m0.000s sys 0m0.062s
## c_read real 0m0.065s user 0m0.000s sys 0m0.046s
## c_regex real 0m0.005s user 0m0.000s sys 0m0.000s
##
testAll_splitIntoArray 1000;
## ===== 1000 fields =====
## c_readarray real 0m0.084s user 0m0.031s sys 0m0.077s
## c_read real 0m0.092s user 0m0.031s sys 0m0.046s
## c_regex real 0m0.125s user 0m0.125s sys 0m0.000s
##
testAll_splitIntoArray 10000;
## ===== 10000 fields =====
## c_readarray real 0m0.209s user 0m0.093s sys 0m0.108s
## c_read real 0m0.333s user 0m0.234s sys 0m0.109s
## c_regex real 0m9.095s user 0m9.078s sys 0m0.000s
##
testAll_splitIntoArray 100000;
## ===== 100000 fields =====
## c_readarray real 0m1.460s user 0m0.326s sys 0m1.124s
## c_read real 0m2.780s user 0m1.686s sys 0m1.092s
## c_regex real 17m38.208s user 15m16.359s sys 2m19.375s
##
이는 비슷한 외곽진입 의해 Jmoney38 사용하지만, sed:
string="1,2,3,4"
array=(`echo $string | sed 's/,/\n/g'`)
echo ${array[0]}
구글 검색 결과 이상이 되는 경향이 있기 때문에 이 질문에 맨 위에 랭크, 내가 하고 싶은 강한 제공하십시오 판독기에서 구분, 그 이후 역시 질문에 대한 답을 언급된 여러 문자 하나 이상의 반응을 보였다.
누가 이 세련된 개확장 매개변수입니다 순결케 BASH 이용하여 솔루션을 제공합니다.
#!/bin/bash
str="LearnABCtoABCSplitABCaABCString"
delimiter=ABC
s=$str$delimiter
array=();
while [[ $s ]]; do
array+=( "${s%%"$delimiter"*}" );
s=${s#*"$delimiter"};
done;
declare -p array
Https://partner. microsoft. [인용 주석문입니다 / referenced 게시물로의] [3]
Https://partner. microsoft. 인용 질문: 따라하기 name 을 문자열으로 분할합니다 멀티 문자 구분 bash?
[3]: https://stackoverflow.com/questions/40686922/howto-split-a-string-on-a-multi-character-delimiter-in-bash # comment82225797_47633817
이 시도하시겠습니까
IFS=', '; array=(Paris, France, Europe)
for item in ${array[@]}; do echo $item; done
IFS=' ';declare -a array=(Paris France Europe)
하지만 그것 없이는 인할지 IFS) 이 추가되고 그들위에 명령취소할 작동하잖아 인스턴스입니다 신선한 배시
이 게시물을 통해 볼 때, 다음과 같은 입력 왔는지 구문 분석 word1, word2.
같은 날 수 없었다. awk 사용하여 이를 해결했다. 도움이 된다면, 누군가.
STRING="value1,value2,value3"
array=`echo $STRING | awk -F ',' '{ s = $1; for (i = 2; i <= NF; i++) s = s "\n"$i; print s; }'`
for word in ${array}
do
echo "This is the word $word"
done
또 다른 방법으로 이 수정 없이 IFS:
read -r -a myarray <<< "${string//, /$IFS}"
우리는 우리의 IFS 변경하는 대신 필요한 항목을 모두 대체할 수 있으며, 일치시키려면 구분, '우리' 와 ',' $ 콘텐트입니다 " " 필요한 구분, if, if / /, / $ $ {} " 문자열이어야 " 통해 ',' 제공합니다.
어쩌면 이렇게 속도가 느릴 경우 매우 큰 문장열 표시되어도?
Tr 분할하려면 구체화하십시오 꽂으십시오 어레이입니다 객체에는 명령을 사용할 수 있습니다. 모두 작동하잖아 MacOS 및 Linux
#!/usr/bin/env bash
currentVersion="1.0.0.140"
arrayData=($(echo $currentVersion | tr "." "\n"))
len=${#arrayData[@]}
for (( i=0; i<=$((len-1)); i++ )); do
echo "index $i - value ${arrayData[$i]}"
done
또 다른 옵션은 IFS 명령을 사용하여
IFS='.' read -ra arrayData <<< "$currentVersion"
#It is the same as tr
arrayData=($(echo $currentVersion | tr "." "\n"))
#Print the split string
for i in "${arrayData[@]}"
do
echo $i
done
예쁜 일인 것은 지루한 의해 분할 문장열 문장열 사용하여 내주었다. 어떤 일이 발생합니까 제한한 것은 우리가 작업하십시오 외곽진입 단 몇 건 (분할되었습니다 ";;;;; ." " /" " 의해 ". 우리는 및 드릴링됩니다) 또는 다양한 부작용은요 config. 출력입니다.
필요한 것이라고 믿고 있다 하지만 난 외곽진입 아래에 몇 가지 요구 사항을 대부분 작동합니까 기동 작전을 수행했다.
#!/bin/bash
# --------------------------------------
# SPLIT FUNCTION
# ----------------
F_SPLIT_R=()
f_split() {
: 'It does a "split" into a given string and returns an array.
Args:
TARGET_P (str): Target string to "split".
DELIMITER_P (Optional[str]): Delimiter used to "split". If not
informed the split will be done by spaces.
Returns:
F_SPLIT_R (array): Array with the provided string separated by the
informed delimiter.
'
F_SPLIT_R=()
TARGET_P=$1
DELIMITER_P=$2
if [ -z "$DELIMITER_P" ] ; then
DELIMITER_P=" "
fi
REMOVE_N=1
if [ "$DELIMITER_P" == "\n" ] ; then
REMOVE_N=0
fi
# NOTE: This was the only parameter that has been a problem so far!
# By Questor
# [Ref.: https://unix.stackexchange.com/a/390732/61742]
if [ "$DELIMITER_P" == "./" ] ; then
DELIMITER_P="[.]/"
fi
if [ ${REMOVE_N} -eq 1 ] ; then
# NOTE: Due to bash limitations we have some problems getting the
# output of a split by awk inside an array and so we need to use
# "line break" (\n) to succeed. Seen this, we remove the line breaks
# momentarily afterwards we reintegrate them. The problem is that if
# there is a line break in the "string" informed, this line break will
# be lost, that is, it is erroneously removed in the output!
# By Questor
TARGET_P=$(awk 'BEGIN {RS="dn"} {gsub("\n", "3F2C417D448C46918289218B7337FCAF"); printf $0}' <<< "${TARGET_P}")
fi
# NOTE: The replace of "\n" by "3F2C417D448C46918289218B7337FCAF" results
# in more occurrences of "3F2C417D448C46918289218B7337FCAF" than the
# amount of "\n" that there was originally in the string (one more
# occurrence at the end of the string)! We can not explain the reason for
# this side effect. The line below corrects this problem! By Questor
TARGET_P=${TARGET_P%????????????????????????????????}
SPLIT_NOW=$(awk -F"$DELIMITER_P" '{for(i=1; i<=NF; i++){printf "%s\n", $i}}' <<< "${TARGET_P}")
while IFS= read -r LINE_NOW ; do
if [ ${REMOVE_N} -eq 1 ] ; then
# NOTE: We use "'" to prevent blank lines with no other characters
# in the sequence being erroneously removed! We do not know the
# reason for this side effect! By Questor
LN_NOW_WITH_N=$(awk 'BEGIN {RS="dn"} {gsub("3F2C417D448C46918289218B7337FCAF", "\n"); printf $0}' <<< "'${LINE_NOW}'")
# NOTE: We use the commands below to revert the intervention made
# immediately above! By Questor
LN_NOW_WITH_N=${LN_NOW_WITH_N%?}
LN_NOW_WITH_N=${LN_NOW_WITH_N#?}
F_SPLIT_R+=("$LN_NOW_WITH_N")
else
F_SPLIT_R+=("$LINE_NOW")
fi
done <<< "$SPLIT_NOW"
}
# --------------------------------------
# HOW TO USE
# ----------------
STRING_TO_SPLIT="
* How do I list all databases and tables using psql?
\"
sudo -u postgres /usr/pgsql-9.4/bin/psql -c \"\l\"
sudo -u postgres /usr/pgsql-9.4/bin/psql <DB_NAME> -c \"\dt\"
\"
\"
\list or \l: list all databases
\dt: list all tables in the current database
\"
[Ref.: https://dba.stackexchange.com/questions/1285/how-do-i-list-all-databases-and-tables-using-psql]
"
f_split "$STRING_TO_SPLIT" "bin/psql -c"
# --------------------------------------
# OUTPUT AND TEST
# ----------------
ARR_LENGTH=${#F_SPLIT_R[*]}
for (( i=0; i<=$(( $ARR_LENGTH -1 )); i++ )) ; do
echo " > -----------------------------------------"
echo "${F_SPLIT_R[$i]}"
echo " < -----------------------------------------"
done
if [ "$STRING_TO_SPLIT" == "${F_SPLIT_R[0]}bin/psql -c${F_SPLIT_R[1]}" ] ; then
echo " > -----------------------------------------"
echo "The strings are the same!"
echo " < -----------------------------------------"
fi