개행 문자로 문자열을 분할하고 읽기를 사용하여 배열에 씁니다.

개행 문자로 문자열을 분할하고 읽기를 사용하여 배열에 씁니다.

문자열이 주어지면 각 필드를 배열 요소에 foo저장하고 싶습니다 . 나는 이전 버전의 bash와 호환되는 명령이나 다른 명령을 사용하여 이 작업을 수행하고 싶었지만 그렇지 않았습니다.\nbarreadreadarray

나는 다음 명령을 시도했습니다.

IFS=$'\n' read -d '' -r -a bar <<< "$foo"

하지만 오류 코드 1만 반환됩니다.

내가 원하는 것을 달성하기 위해 사용할 수 있는 명령이 있습니까? 이 작업을 반복적으로 수행할 수 있다는 것을 알고 있지만 단 하나의 명령으로 수행하는 것이 더 좋습니다.

답변1

read문자열에 구분 기호가 없으므로 1을 반환합니다. 그러나 배열은 채워집니다.

$ echo "$BASH_VERSION"
3.2.57(1)-release
$ foo=$'one\ntwo\nthree\nfour'

$ IFS=$'\n' read -d '' -r -a bar <<<"$foo"
$ echo $?
1
$ declare -p bar
declare -a bar='([0]="one" [1]="two" [2]="three" [3]="four")'

비어 있지 않은 구분 기호를 사용하면 0이 아닌 결과가 생성됩니다.

$ unset bar
$ IFS=$'\n' read -d "\034" -r -a bar <<<"${foo}\034"
$ echo $?
0
$ declare -p bar
declare -a bar='([0]="one" [1]="two" [2]="three" [3]="four")'

8진수 34는 ASCII "파일 구분 기호" 문자이며너무 가능하지 않음귀하의 데이터에 나타납니다.

답변2

@glenn jackman의 첫 번째 솔루션의 약간 더 짧은 변형: 주어진

foo=$'one\ntwo\nthree\nfour'

, Bash가 하도록 놔두겠습니다모두일하다:

set -o noglob         # See special Note, below.
IFS=$'\n' bar=($foo)
set +o noglob         # See special Note, below.

괄호는 요소가 괄호의 내용인 배열을 초기화하고 있음을 Bash에게 알려줍니다. 그게 다입니다.

추가하려면 수정하세요.      노트:*입력 줄에 또는 ?( man 7 glob전체 목록 포함)과 같은 와일드카드 메타 문자가 포함될 수 있는 경우 이를 일시적으로 비활성화하여 파일 이름 확장을 방지해야 합니다 noglob. 고든 데이비슨!



유효한 것으로 확인됨:

echo ${#bar[@]}
4

, 그리고

echo "[0]:'${bar[0]}' ... [3]:'${bar[3]}'"
[0]:'one' ... [3]:'four'


echo "$BASH_VERSION"
4.1.2(2)-release

관련 정보