extrai string entre aspas duplas

2

Eu tenho requisito que preciso extrair string usando aspas. Minha string da seguinte forma.

"abcd efgh" "ijkl mnop" "qrst uvwxyz"

você pode me ajudar a obter a string entre aspas duplas ( ijkl mnop ) usando o comando sed ou grep .

Em outras palavras, se eu disser me dar a string entre aspas, eu quero a primeira string; se eu disser segunda string, ela deve me fornecer uma string entre aspas duplas e, da mesma forma, a terceira também.

    
por siva 17.06.2015 / 21:28

3 respostas

2

Não sei ao certo como você deseja inserir a string. Isso tem o efeito que você deseja alcançar, mas pode precisar ser modificado de acordo com a entrada da string:

aa() { echo $3 ; } ; aa "abcd efgh" "ijkl mnop" "qrst uvwxyz"

Edit: Então, se estiver na variável (tem que ser definido com aspas "):

AA="\"abcd efgh\" \"ijkl mnop\" \"qrst uvwxyz\""
echo $AA

então:

FIRST='echo $AA| awk -F \" '{print $2}''
SECOND='echo $AA| awk -F \" '{print $4}''
THIRD='echo $AA| awk -F \" '{print $6}''
echo $FIRST : $SECOND : $THIRD

como jasonwryan apontou acima. Você disse, você queria usar sed, mas isso torna desnecessário complexo:

FIRST='echo $AA| sed 's/^\"\([^\"]*\)\".*//''
SECOND='echo $AA| sed 's/^\"[^\"]*\" \"\([^\"]*\)\".*//''
THIRD='echo $AA| sed 's/^\"[^\"]*\" \"[^\"]*\" \"\([^\"]*\)\".*//''

Edit2: Na verdade, é possível alcançar completamente sem sed, awk, perl, .. apenas com bash, usando sua função de "leitura" embutida como essa (os ecos são para depuração):

#!/bin/bash

aa() {
echo '$1'="$1"
IFS=\" read aaa FIRST bbb SECOND ccc THIRD ddd <<< "$1"
echo FIRST=$FIRST : SECOND=$SECOND : THIRD=$THIRD
}

AA="\"abcd efgh\" \"ijkl mnop\" \"qrst uvwxyz\""
echo '$AA'="$AA"
aa "$AA"
    
por 17.06.2015 / 21:49
2

Você disse isso em um comentário:

above string is in variable. I need to extract each section(first,second,third) and store it different variables

Então vamos dividir isso.

IFS=\"                  #set the shell's field separator
set -f                  #don't try to glob 
set -- $var             #split on $IFS
var1=$2 var2=$4 var3=$6 #yay
unset IFS               #restore something like a sane default

Isso não vai lidar com seqüências de caracteres que podem conter citações com escape de barra invertida, no entanto. Espero que isso não seja um problema, porque eu não gosto de fazer isso.

    
por 18.06.2015 / 00:01
1

Criando (e simplificando um pouco) a resposta sed de ludvik02:

AA='"abcd efgh" "ijkl mnop" "qrst uvwxyz"'
AA1=$(echo "$AA" | sed -r 's/^([^"]*"){1}([^"]*).*//')
AA2=$(echo "$AA" | sed -r 's/^([^"]*"){3}([^"]*).*//')
AA3=$(echo "$AA" | sed -r 's/^([^"]*"){5}([^"]*).*//')
(Note that                        this ↑                        is different on every line.)

A opção -r para sed ativa expressões regulares estendidas. Precisamos usar {n} , o que significa n ocorrências da regex precedente. ([^"]*") é um regex composto (grupo) que corresponde qualquer número de caracteres diferente de " , terminado por " . A string de entrada de exemplo pode corresponder a essa regex até seis vezes (porque tem seis " caracteres); com ... s inserido para distinguir as lacunas entre as cordas, essas ocorrências são

"abcd efgh" ... "ijkl mnop" ... "qrst uvwxyz"
↑↑--------↑↑----↑↑--------↑↑----↑↑----------↑
1    2       3       4       5        6

Corresponde a qualquer número ímpar (por exemplo, três) de ocorrências do que consome tudo até e incluindo o n th (por exemplo, terceiro) " caractere, ou seja, o caractere " no início de a string ((n+1)/2) th (por exemplo, segundo) entre aspas. Então ([^"]*) corresponde (e grupos) a tudo (mas não incluindo) o caractere (n+1) th " , isto é, o caractere " no final da segunda cadeia de caracteres entre aspas. Portanto, esse grupo (o segundo grupo) corresponde à segunda string citada. Finalmente, .* consome o restante da string de entrada. Então, substituímos toda a linha de entrada por , o valor do segundo grupo:

"abcd efgh" ... "ijkl mnop" ... "qrst uvwxyz"
↑↑--------↑↑----↑⇑=======⇑⇈≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡⇈
1    2       3
↑---------------↑⇑=======⇑⇈≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡⇈
                            (unnamed)
    
por 17.06.2015 / 23:56