명령 출력에서 ​​따옴표로 묶인 문자열의 내용을 어떻게 추출합니까?


26

VBoxManage list vms다음과 같은 출력 이 있습니다.

"arch" {de1a1db2-86c5-43e7-a8de-a0031835f7a7}   
"arch2" {92d8513c-f13e-41b5-97e2-2a6b17d47b67}  

나는 이름을 잡기 위해 필요 arch하고 arch2그리고 변수에 저장합니다.

답변:


34

grep + sed 사용

이 두 문자열의 내용을 구문 분석합니다.

$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2

위의 패턴과 일치하는 문자열을 찾습니다 ".*". 큰 따옴표 안에있는 모든 항목과 일치합니다. 따라서 grep이러한 유형의 값을 반환합니다.

"arch"
"arch2"

파이프 sed는이 문자열에서 큰 따옴표를 제거하여 찾고있는 문자열을 제공합니다. 이 표기법 sed 's/"//g'sed검색을 수행하고 큰 따옴표의 모든 어커런스를 대체하고 아무것도 대체하지 않도록 지시 합니다 s/"//g. 명령 s/find/replace/g은 거기에서 진행되고 있으며, 후행 g은 주어진 전체 문자열에서 전역 적으로 수행하도록 지시합니다.

그냥 sed를 사용하여

sed시작하는 큰 따옴표를 잘라 내고 그 사이에있는 것을 유지하고 남은 따옴표와 그 이후의 모든 것을 잘라 내기 위해 사용할 수도 있습니다 .

$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2

다른 방법

$ grep -o '".*"' somefile | tr -d '"'
arch
arch2

명령 tr을 사용하여 문자를 삭제할 수 있습니다. 이 경우 큰 따옴표를 삭제합니다.

$ grep -oP '(?<=").*(?=")' somefile
arch
arch2

사용 grep당신은 큰 따옴표와 큰 따옴표 또는 종료로 시작하고 바로 문자열을보고 어떤 문자열을 찾아 '의 PCRE 기능을 할 수 있습니다.


1
tr -d \"따옴표를 삭제하는 또 다른 방법입니다. ( tr일반적으로 한 문자 세트를 다른 문자 세트로 변환 -d하고 대신 삭제하도록 지시합니다.)
deltab

1
SLM - 당신이를 추가하는 경우 /address/sed같은 sed '/^"\(arch[^"]*\)/s//\1/당신이 해당 문자열이 포함 된 라인에서 작동 할 수 있습니다.
mikeserv 2016 년

1
@mikeserv-사실, 아치가 그의 출력에 얼마나 일관성이 있는지 확실하지 않았습니다. 그러나 그렇다면 그것이 효과가 있습니다.
slm

1
좋은 지적이야. 일관된 징후는 없습니다. 죄송합니다.
mikeserv 2016 년

2
방금 줄에 두 개의 큰 따옴표가있는 경우를 대비 하여 sed실제로해야 한다는 것을 깨달았습니다 s/^"\([^"]*\)".*/\1/.
mikeserv

19

그것은 또 다른 직업입니다 cut.

VBoxManage list vms | cut -d \" -f2

3
매우 깔끔합니다! 작동 방식 : cut따옴표를 구분 기호로 사용하여 각 줄을 필드로 분할 한 다음 필드 2를 출력합니다. 필드 1은 첫 번째 따옴표 앞의 빈 문자열이고, 필드 2는 따옴표 사이의 원하는 문자열이고 필드 3은 나머지 부분입니다. 선.
deltab

7

로에게 sed당신이 할 수 있습니다 :

var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')

설명:

  • s/.../.../ -일치 및 교체
  • ^-라인 시작시 일치
  • \(...\) -이것은 역 참조이므로 나중에 여기에서 일치하는 것을 참조 할 수 있습니다. \1
  • [^"]*-를 포함하지 않는 시퀀스와 일치합니다 "(즉, 다음 시퀀스 까지 ").
  • .* -나머지 줄과 일치
  • \1 -역 참조로 교체

또는과 awk:

var=$(VBoxManage list vms | awk -F\" '{ print $2 }')

현대 쉘에서는 일반 변수 대신 배열을 사용할 수도 있습니다. 에서 bash당신이 할 수 있습니다 :

IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"

변수를 사용할 때 더 쉬울 수 있습니다.


sed 명령을 제게 해줄 래요?
Harrys Kavan 2016 년

5

bash를 사용하여 다음과 같이 작성합니다.

while read vm value; do
    case $vm in
        '"arch"') arch=$value ;;
        '"arch2"') arch2=$value ;;
    esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2

5

그리고 --perl-regexp옵션을 가진 하나의 라이너를 통해

VBoxManage list vms | grep -oP '(?<=^\")[^"]*'

설명:

(?<=^\")[^"]*-> 여기에 lookbehind가 사용됩니다. 모든 문자와 일치하지만 "0 번 이상 일치하지 않습니다 (한 번 큰 따옴표를 찾으면 일치하지 않습니다). 큰 따옴표 바로 뒤에 있습니다 (큰 따옴표로 시작하는 줄 만).

또 다른 미운 해킹을 통해 sed,

$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2

0

정규식에는 욕심 많은 모드와 욕심없는 모드가 있으므로 같은 줄에 여러 개의 대상이 있으면 원하는대로 추출하지 않습니다. 선:

"tom" is a cat, and "jerry" is a mouse. 

목표:

tom
jerry

명령 (욕심쟁이 모드) :

grep -oP '".*"' name

명령 (비 욕심 모드) :

grep -oP '".*?"' name
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.