Como posso obter os valores entre aspas simples ou duplas?

0

Supondo uma linha como esta:

foo bar ENV['PGHOST'] another bar

Eu gostaria de obter o valor PGHOST que está dentro dos colchetes ao lado do ENV . Eu suponho que a linha tenha apenas uma ocorrência desse tipo. Então, isso: foo bar ENV['PGHOST'] another bar ENV['FOO'] and foo não é uma entrada.

No entanto, a linha pode estar chegando com " em vez de ' , assim:

foo bar ENV["PGHOST"] another bar

Em outras palavras, o valor que desejo obter pode ser colocado entre aspas duplas ou simples.

Não apenas isso, o valor real pode conter aspas duplas ou simples. Se estiver entre aspas simples, pode conter uma aspa dupla. Se estiver entre aspas duplas, pode conter uma aspa simples. Então, essas duas linhas são entradas esperadas válidas:

foo bar ENV["PGH'OST"] another bar
foo bar ENV['PGH"OST'] another bar

Se eu receber linhas como as acima, o resultado deve ser PGH'OST e PGH"OST , respectivamente.

Eu sei como posso obter o valor se ele não contiver aspas entre aspas. Aqui está como eu faço:

SED_COMMAND="s/^.*ENV\[['\"]\([^'\"]*\)['\"]\].*$//"
echo $input | sed ${SED_COMMAND}

Portanto, o acima funciona bem para input sendo foo bar ENV['PGHOST'] another bar ou foo bar ENV["PGHOST"] another bar , por exemplo.

Mas não funciona para foo bar ENV['PG"HOST'] another bar , nem para foo bar ENV["PG'HOST"] another bar .

Qualquer ajuda seria muito apreciada. Observe que não preciso resolver o problema com sed . Qualquer outra sugestão é aceitável.

Atualizar . Note que eu posso ter entradas como esta:

foo bar ENV['PGHOST'] another bar "what a world" I 'live' in
foo bar ENV["PGHOST"] another bar "what a world" I 'live' in

i.e. aspas duplas e / ou únicas podem existir em partes da entrada que estão fora da chave ENV que desejo extrair.

Atualizar Outro exemplo de entrada válida:

foo bar ENV['PGHOST'] another bar in NEW['YORK'] to visit

pode ser uma entrada válida. Eu preciso obter PGHOST .

E isso também é válido:

foo bar ENV["PGH'OST"] another bar ["baz"]

que deve retornar PGH'OST .

    
por p.matsinopoulos 10.05.2018 / 08:59

3 respostas

1

O seguinte script Bash mais circunspecto remove primeiro o caracter após a primeira ocorrência de ENV [e tudo antes dele e depois remove o caractere antes da primeira ocorrência de] e depois de tudo. Por favor, diga se você tiver outros casos que impedem este trabalho como pretendido.

x="foo bar ENV['PGHOST'] another bar in NEW['YORK'] to visit"; 
x=${x#*ENV[?}; x=${x%%?]*}; echo $x

A seguinte versão irá ler um arquivo chamado 'input' e escrever o resultado em um campo chamado 'output'.

cd ~/Desktop; 
while IFS= read -r x; 
do x=${x#*ENV[?}; echo ${x%%?]*} >> output;  
done < input 

Se "entrada" contiver:

foo bar ENV['PGHOST'] another bar
foo bar ENV["PGHOST"] another bar
foo bar ENV["PGH'OST"] another bar
foo bar ENV['PGH"OST'] another bar
foo bar ENV['PGHOST'] another bar "what a world" I 'live' in
foo bar ENV["PGHOST"] another bar "what a world" I 'live' in
foo bar ENV['PGHOST'] another bar in NEW['YORK'] to visit
foo bar ENV["PGH'OST"] another bar ["baz"]

então, o seguinte será gravado em 'output':

PGHOST
PGHOST
PGH'OST
PGH"OST
PGHOST
PGHOST
PGHOST
PGH'OST
    
por 11.05.2018 / 16:03
1

O script Bash a seguir deve ser removido:

1 - tudo até e incluindo o primeiro [mais um caractere depois dele

2 - o primeiro] e tudo depois dele e mais um antes dele.

x="foo bar ENV['PGHOST'] another bar"; x=${x#*[?}; x=${x%%?]*}; echo $x 

A primeira tentativa não foi exibida como esperado até que eu induza 4 espaços.

Agora mudou para remover tudo após o primeiro].

Acho que isso deve funcionar em todos os casos existentes, mas você pode adicionar mais casos.

    
por 10.05.2018 / 23:49
0
$ SED_COMMAND="s/^.*ENV\[\(.\)\(.*\)\].*$//"

$ cat input
foo bar ENV['PGHOST'] another bar
foo bar ENV['PGHO"ST'] another bar
foo bar ENV["PGHO'ST"] another bar
foo bar ENV["PGHOST"] another bar

foo bar ENV['PGHOST'] another bar "what a world" I 'live' in
foo bar ENV["PGHOST"] another bar "what a world" I 'live' in

foo bar ENV['PGHOST'] another bar in NEW['YORK'] to visit
foo bar ENV["PGH'OST"] another bar ["baz"]


$ cat input | sed ${SED_COMMAND}
PGHOST
PGHO"ST
PGHO'ST
PGHOST

PGHOST
PGHOST

PGHOST'] another bar in NEW['YORK
PGH'OST"] another bar ["baz

Funciona para quase todo o seu absurdo bobo. Exceto os dois últimos, você precisará do perl para fazer isso porque sed não tenha recursos não gananciosos , ou elimine as aspas dentro dos colchetes e use [: alpha:] ou \ w. Tudo o que mudei foi assumir que a aspas ('ou') que delimita a palavra a ser capturada segue diretamente a chave de abertura [, e então captura as aspas com . , para capturar o 'ou' e usado como delimitador final para a referência back \ 2. Então, usando sed como você fez, traduziu a linha inteira para apenas a parte que você deseja capturar.

    
por 11.05.2018 / 00:02

Tags