따옴표 안에 일련의 문자열을 출력하는 함수(내가 만든 것이 아님)가 있습니다.
command <args>
“Foo”
“FooBar”
“Foo Bar”
“FooBar/Foo Bar”
배열(Bash, BSD/Mac)에 할당하려고 하면 4개가 아닌 7개의 요소가 표시됩니다. 예를 들어, ${array[2]}
나 에게~해야 한다get 이지만 대신 “Foo Bar”
내가 얻는 ”Foo
다음 요소 는 Bar”
.any 요소 입니다.아니요공백은 잘 작동합니다(예 ${array[0]}
: "Foo")
요소 자체가 공백(?)으로 구분되는 배열에 따옴표(공백 포함) 사이의 각 요소를 할당하는 방법은 무엇입니까?
이제 sed/awk를 사용하여 따옴표를 "제거"하는 것을 고려하고 있지만 더 좋고 효율적인 방법이 있어야 한다고 생각합니다.
현재 저는 명령의 출력(따옴표를 포함하여 위의 출력과 정확히 동일함)을 임시 변수에 할당한 다음 이를 배열에 할당합니다.
_tempvar=“$(command <args>)”
declare -a _array=(${_tempvar})
답변1
에서는 파일의 행이나 일부 명령의 출력을 배열로 읽을 bash
수 있습니다 .readarray
오직 이 기능은 2009년에 출시된 버전 4.0에 추가되었지만 macOS는 여전히 bash 3.2와 함께 제공됩니다.
macos는 zsh와 함께 제공되지만 이것이 더 나은 쉘입니다.
비어 있지 않은 명령 출력 줄을 얻으려면 f
인수 확장 플래그를 사용하여 f
분할 하고( eed 줄에서 분할) 연산자 기호 를 사용하여 "
(U+0022), “
(U+0201C) 및 ”
(U+ 201D) 문자를 제거할 수 있습니다. ${var//pattern[/replacement]}
와 같은:
#! /bin/zsh -
array=( ${(f)${"$(cmd)"//['"“”']}} ) || exit
U+0022 ASCII 문자로 인용된 문자열이고 인용문이 언어에서 인용문이 작동하는 방식과 호환되는 경우 / 플래그(언어 구문 분석기와 동일한 방식으로 텍스트를 표시하기 위해) 및 플래그를 zsh
사용할 수도 있습니다. (따옴표를 제거하기 위해) 한 줄로 나누는 대신(따옴표 붙은 문자열이 여러 줄에 걸쳐 있을 수 없다고 가정)z
Z
Q
#! /bin/zsh -
array=( ${(Q)${(Z[n])"$(cmd)"}} ) || exit
당신의
declare -a array=(${tempvar})
in은 bash
따옴표가 없는(보통 의도하지 않게) 확장될 때 호출되는 분할+glob 연산자를 사용합니다. 복잡한 알고리즘을 사용하여 출력을 $IFS
특수 매개변수의 문자(bash에서는 기본적으로 공백, 탭 및 개행 문자 포함)로 분할하고 결과 단어는 다음과 같습니다.와일드카드또한 ~으로 알려진파일 이름 생성(이것은 거의 바람직하지 않습니다).
여기서는 분할+glob을 사용하여 명령 출력의 비어 있지 않은 줄을 가져올 수 있지만 먼저 이를 조정해야 합니다.
IFS=$'\n' # split on newline only:
set -o noglob # disable the glob part which we don't want
array=( $(cmd) ) # split+glob
"“”
그런 다음 with 를 제거할 수도 있지만 ${var//pattern[/replacement]}
bash에서는 인수 확산 연산자를 누적할 수 없고 구문(ksh93에서 상속됨)이 약간 어색하기 때문에 나중에 수행해야 합니다.
array=( "${array[@]//['"“”']}" )
이 방법과 달리 zsh
다음과 같은 작업은 처리하지 않습니다 "foo \"bar\" and \\backslash"
.
답변2
공백으로 인해 토큰화가 발생하므로 7개의 요소를 얻습니다.
IFS=$'\n'
문자열을 배열에 추가하기 전에 설정하면 4개의 요소가 표시되지만 큰따옴표가 포함됩니다.
예:
IFS=$'\n'
arr=($(command <args>))
따옴표 없이 4개의 요소를 원하는 경우 다음을 수행하십시오.
IFS=$'\n'
arr=($(command <args> | sed s'#"##'g))
완전한 예:
IFS=$'\n'
# tst.txt has your strings:
arr=($(cat tst.txt | sed s'#"##'g))
declare -p arr
산출:
declare -a arr=([0]="Foo" [1]="FooBar" [2]="Foo Bar" [3]="FooBar/Foo Bar")
답변3
readarray -t array <<< $(echo $'"a a"\n"b b"\n"c c"')
declare -p array
declare -a array=([0]="\"a a\"" [1]="\"b b\"" [2]="\"c c\"")
readarray -t array <<< $(command <args>)