다음 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
. 일반적인 방법으로 배열을 사용할 수 있습니다(예: 각 요소에 대해 하나씩 단어 목록으로 확장).foo
bar
"${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