Sed para excluir entre os delimitadores, mas mantenha o primeiro delimitador

1

Preciso excluir tudo entre o segundo = em uma string e o primeiro / em uma string, mas mantenha o = no lugar. Eu tentei muitas, muitas coisas, a mais recente das quais é

sed -i 's/=[^/]*//
    
por Jeff Carson 28.09.2016 / 23:46

3 respostas

1

Comecei a escrever sobre asserções de look-ahead e look-behind apenas para saber que sed não as suporta! Isso deve fazer o truque:

sed -i 's!\(=[^=]*=\)[^/]*/!!'

  • Como usamos o caractere / no regexp, alteramos o delimitador do comando s para !
  • \(=[^=]*=\) é um grupo de captura que corresponde a um caractere = seguido por zero ou mais outros caracteres seguidos por outro caractere = . Esta parte é necessária para garantir que haja dois caracteres = antes da substring a ser excluída conforme você disse que precisa
  • [^/]*/ corresponde ao que está entre os delimitadores e o segundo delimitador
  • substitui toda a cadeia combinada pelo que corresponde ao grupo de captura \(=[^=]*=\)
por 29.09.2016 / 05:42
2

Com base apenas na descrição do texto, sem entrada / saída de amostra, eu criei isto:

$ echo "foo=bar=baz/quux" | sed 's/\(.*=.*\)=.*\/\(.*\)/=/'
foo=bar=quux

Quão perto isso chega ao que você quer?

    
por 28.09.2016 / 23:56
0

Aqui está uma solução com perl

$ echo 'foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
foo=bar=quux

$ echo 'abc=foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
abc=foo=bar=baz/quux

Como pode ser visto nos exemplos acima, isso restringe a exclusão de texto apenas do segundo = para /

  • ^([^=]+=){2}\K do início da linha encontra 2 da sequência de não = texto seguido de = . O \K significa lookbehind positivo, não faz parte da string de substituição
  • [^=/]+/ significa um ou mais caracteres que não são =/ e terminam com /
    • Se tal texto for encontrado, ele será excluído

Mesma solução com sed

$ echo 'foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/||'
foo=bar=quux

$ echo 'abc=foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/||'
abc=foo=bar=baz/quux

Ele não suporta construções lookahead / lookbehind, portanto, capture o grupo usado e backreferenced enquanto substitui

    
por 29.09.2016 / 06:11