구분 기호를 사용할 때 readarray로 추가된 새 줄을 제거하는 방법은 무엇입니까?

구분 기호를 사용할 때 readarray로 추가된 새 줄을 제거하는 방법은 무엇입니까?
VAR=a,b,c,d
# VAR=$(echo $VAR|tr -d '\n')
echo "[$VAR]"
readarray -td, ARR<<< "$VAR"
declare -p ARR

결과:

[a,b,c,d]
declare -a ARR=([0]="a" [1]="b" [2]="c" [3]=$'d\n')

readarray마지막 개행 문자를 추가하지 않는지 어떻게 알 수 있나요 \n? 최신 기호는 무엇을 의미하나요 $?

답변1

암시적 후행 개행 문자는 다음과 같습니다.아니요readarray내장 에 의해 추가되었지만 here-string( <<<) 에 의해 추가되었습니다 bash. 참조bash here-string이 후행 줄 바꿈을 추가하는 이유는 무엇입니까?. 개행 없이 문자열을 인쇄 하고 프로세스 대체 기술을 사용하여 문자열을 읽으면 printf이러한 상황을 없앨 수 있습니다.< <()

readarray -td, ARR < <(printf '%s' "$VAR")
declare -p ARR

이제 올바르게 생성됩니다

declare -a ARR=([0]="a" [1]="b" [2]="c" [3]="d")

답변2

분할+글로브(목록 컨텍스트에서 따옴표 없이 확장을 유지하면 발생하는 현상)를 사용할 수 있습니다. 대부분의 경우 방해가 되므로 정말로 필요할 때 사용하지 않는 것은 부끄러운 일입니다.

IFS=,
set -o noglob

ARR=($VAR) # split+glob with glob disabled, and split using , as delimiter

이는 임시 파일을 작성한 다음 메서드에서처럼 호출하는 것보다 readarray간단합니다 ( 최신 버전이 필요하다는 readarray <<< "$string"점도 참고하세요 ).readarray -dbash

S( 는IFS분할기), readarrayand로 분할하는 것과 동일한 방식으로 작동합니다.a,,b,"a""""b"

진정한 분할 연산자의 경우 다음을 사용할 수 있습니다 zsh.

ARR=("${(@s:,:)VAR}")

( @및 큰따옴표는 빈 요소를 유지합니다).

답변3

@StéphaneChazelas 답변의 미리 준비된 버전:

# usage: setarray varname sep string
setarray(){ declare -n a=$1; local IFS=$2 -; set -f; a=($3); }

$ setarray arr , 1,2,3,
$ declare -p arr
declare -a arr=([0]="1" [1]="2" [2]="3")

$ setarray path : "$PATH"
$ setarray ld_preload ': ' "$LD_PRELOAD" # its elements can be separated by either ':' or spaces
...

변수와 마찬가지로 ( ) local -와 같은 옵션을 함수에 로컬로 만듭니다 .set -fnoglob

declare -n a=$1만들 것입니다현지의변수는 (함수의 첫 번째 매개변수)라는 a이름의 전역 변수에 대한 별칭 역할을 합니다.$1

관련 정보