문자열이 주어지면 각 필드를 배열 요소에 foo
저장하고 싶습니다 . 나는 이전 버전의 bash와 호환되는 명령이나 다른 명령을 사용하여 이 작업을 수행하고 싶었지만 그렇지 않았습니다.\n
bar
read
readarray
나는 다음 명령을 시도했습니다.
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