cant não combinando caracteres curinga avidamente para cortar partes da cadeia de caracteres

5

Eu tenho essa string

extension_dir => /some/path/php/extensions/no-debug-non-zts-20160303 => /some/path/php/extensions/no-debug-non-zts-20160303
sqlite3.extension_dir => no value => no value

qual é a saída de php -i | grep extension_dir .

Como posso analisá-lo no bash para obter o primeiro /some/path/php/extensions/no-debug-non-zts-20160303 ?

Até agora eu tentei:

echo $(php -i | grep extension_dir | sed 's/extension_dir => //g' | sed 's/=> .*//g')

mas isso me dá /some/path/php/extensions/no-debug-non-zts-20160303 sqlite3.no value . Não tenho ideia de por que não substitui todas as correspondências de => .*

Minha idéia básica é livrar-se do primeiro extension_dir => e livrar-se de tudo depois do primeiro => incluindo => Provavelmente sed combina as coisas de maneira diferente do regex.

    
por simPod 16.02.2018 / 12:38

4 respostas

8
php -i | sed -n '/extension_dir/{s/^[^/]*//;s/ *=>.*$//;p;}'

ou, como sugerido nos comentários abaixo,

php -i | sed '/extension_dir/!d;s/[^/]*//;s/ *=>.*//'

O sed acima substitui seu grep e, para cada linha que corresponda a extensions_dir , primeiro removerá tudo até o primeiro / e depois tudo, desde o primeiro => no modificada string. Todos os espaços antes do => também são removidos. As linhas que não correspondem a extensions_dir são ignoradas.

Isso retornará o caminho desejado para a primeira linha de entrada e uma linha vazia para o segundo.

Para desconsiderar a segunda linha de entrada, use /^extension_dir/ em vez de /extension_dir/ no sed acima. Isso descartará a segunda linha, pois não inicia com essa string.

É a combinação de seus dois scripts sed que produz o resultado surpreendente para a segunda linha de entrada.

A linha é

sqlite3.extension_dir => no value => no value

e o primeiro sed modificará isso para

sqlite3.no value => no value

O segundo sed removerá o bit => no value no final.

Note que

echo $( ... )

é um pouco inútil, pois engole as novas linhas na saída do comando dentro de $( ... ) . Em vez disso teste com apenas o comando sem a substituição do comando echo ou $( ... ) .

É possivelmente esse uso de echo que você confundiu sobre a natureza da saída de php -i e grep (duas linhas de correspondência em vez de uma).

    
por 16.02.2018 / 12:46
7

Eu posso te dar uma solução simples para o awk.

php -i | awk -F ' => ' '/extension_dir/{print $2; exit}'

Isso funcionará se você quiser perder o sed.

EDIT: Movido sair para dentro do bloco para evitar um erro de sintaxe, adicionar espaços ao redor do separador de campo para que não sejam exibidos com o caminho de arquivo resultante e descrever a alteração no corpo, para que o stackexchange permita a edição devido à alteração mínima de caracteres limitação.

    
por 16.02.2018 / 12:46
2

Se o caminho não contiver espaços, esta expressão será suficiente:

php -i | grep -Po 'extension_dir => \K/[^ ]*'

Entrada

extension_dir => /some/path/php/extensions/no-debug-non-zts-20160303 => /some/path/php/extensions/no-debug-non-zts-20160303
sqlite3.extension_dir => no value => no value

Resultado

/some/path/php/extensions/no-debug-non-zts-20160303
    
por 16.02.2018 / 13:13
-1
echo $(php -i | grep -Poie '/some/path/php/extensions/no-debug-non-zts-20160303')
    
por 17.02.2018 / 13:37

Tags