따옴표로 묶인 값이 포함된 문자열을 공백으로 분할하는 방법

따옴표로 묶인 값이 포함된 문자열을 공백으로 분할하는 방법

다음 bash 예제를 살펴보세요(실제 출력은 에서 나온다는 점을 언급해야 합니다 vboxmanage list vms).

TEST='"ubuntu server" foo bar'
echo $TEST
"ubuntu server" foo bar

(루프 또는 별도의 변수에서) 세 값을 어떻게 분리할 수 있나요? 내가 찾은 모든 솔루션은 공백 구분 기호에 의존하고 첫 번째 값을 파괴합니다.

답변1

VirtualBox 시스템의 이름을 반복할 수 있습니다.

vboxmanage list -l vms | sed -n 's/^Name:[[:blank:]]*//p' |
while IFS= read -r vm_name; do
   printf 'There is one VM called "%s"\n' "$vm_name"
done

긴 형식을 사용하여 시스템을 나열하고 이름을 구문 분석합니다. 그런 다음 이러한 이름은 쉘 루프에서 읽혀지고 각 이름에 대해 짧은 메시지가 인쇄됩니다.

이름을 배열로 읽을 수도 있습니다.

readarray -t vm_names < <(vboxmanage list -l vms | sed -n 's/^Name:[[:blank:]]*//p')
printf 'There is one VM called "%s"\n' "${vm_names[@]}"

여기에서는 이름 목록이 빨간색으로 배열에 입력됩니다 vm_names. 다음과 같이 이 배열을 반복할 수 있습니다.

for vm_name in "${vm_names[@]}"; do
   # Use "$vm_name" here
done

UUID를 사용할 수도 있습니다.

vboxmanage list -l vms |
sed -n \
    -e '/^Name:[[:blank:]]*/{ s///; h; }' \
    -e '/^UUID:[[:blank:]]*/{ s///; G; y/\n/@/; p; }' |
while IFS=@ read -r vm_uuid vm_name; do
    printf 'VM "%s" has UUID "%s"\n' "$vm_name" "$vm_uuid"
done

답변2

"ubuntu server" foo bar초기 질문(예: ) 의 코드 블록에 표시된 형식의 문자열로 가정하면,알려진 데이터는 충분합니다., 즉 eval평가를 위해 셸 명령의 일부로 사용할 수 있는 인용부호 전용 문자열(셸 특수 문자 없음)입니다.

str='"ubuntu server" foo bar'
eval "arr=($str)"

arr이 입력을 사용하면 , 및 3개의 요소가 있는 배열이 제공됩니다 ubuntu server. 일반적인 방법으로 배열을 사용할 수 있습니다(예: 각 요소에 대해 하나씩 단어 목록으로 확장).foobar"${arr[@]}"

그러나 사용법에는 eval따옴표뿐만 아니라 모든 쉘 구문 값을 평가하는 작업이 포함됩니다. 예를 들어, 문자열에 명령 대체가 포함되어 있으면 $(cmd...)해당 명령이 실행됩니다. 문자열에 따옴표가 포함되어 있지 않으면 );복합 할당 문이 종료되고 뒤따르는 내용이 쉘 명령으로 실행됩니다.

안전을 확보하려면 먼저 입력의 유효성을 검사하십시오. 예를 들어 따옴표와 안전한 문자만 포함되어 있는지 확인하십시오. 예를 들어 문자, 숫자, 공백, 밑줄 및 두 가지 유형의 따옴표를 모두 허용합니다.~해야 한다주의하시기 바랍니다. 입력에 여전히 일치하지 않는 따옴표가 있을 수 있으며 이로 인해 eval.

re='[^[:alnum:][:blank:]_'\''"]'
if [[ "$str" =~ $re ]]; then
    echo "unsafe input" >&2
else
    eval "arr=($str)";
    if [[ $? -ne 0 ]]; then
        echo "error in assignment" >&2
    fi
fi

답변3

단어 분할을 위해 set 명령을 사용할 수 있습니다. 서투른 시도이지만 개선할 수는 있을 것입니다.

먼저 구분 기호를 큰따옴표로 설정합니다.

IFS='"'

그 다음에

set -- $TEST
echo $1

echo $2
ubuntu server
echo $3
 foo bar

첫 번째(2단어) 변수는 $2에 있고 나머지 변수는 $3에 있습니다.

a=$2
b=$3

이제 변수 b에 대해 다른 작업을 수행하되 이번에는 공백 구분 기호를 사용합니다.

IFS=' '
set -- $b
echo $1
foo
echo $2
bar

관련 정보