Por que o sed output -e expression # 1, char 55: expressão regular precedente inválida

1

Estou tentando escrever o comando sed para encontrar e substituir um valor key = em uma string delimitada por vírgulas.

Exemplo de string no arquivo: KEY_1=value_1,KEY_2=value_2,SOMEKEY=lastValue

O comando sed usado:

sed -r 's/KEY_2=.*?((?=,)|$)/KEY_2=new_value/' myFile.txt

Se a chave existir, substitua-a e seu valor por uma nova chave = valor. A maioria dos valores terminará com uma vírgula ',' no entanto, o caso periférico é a última chave = valor na seqüência de caracteres não terá um,.

Está me dando a seguinte mensagem de erro na VM RedHat Linux

sed: -e expression #1, char 55: Invalid preceding regular expression

que eu acredito que é o último '/' eu tentei / g que também seria exctable como nenhuma chave deve ser duplicada na string original.

    
por Fisher_Coder 26.09.2018 / 04:05

2 respostas

3

O utilitário sed não suporta expressões regulares semelhantes a Perl.

Em vez disso, você pode usar

$ sed 's/KEY_2=[^,]*/KEY_2=new value/' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue

ou

$ sed 's/\(KEY_2\)=[^,]*/=new value/' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue

Ou, com awk (sem usar expressões regulares e, em vez disso, usando correspondências de cadeia exata nas chaves, o que evita confusões quando você tem os dois KEY_2 e SOME_OTHER_KEY_2 ):

$ awk -F, -v OFS=, '{ for (i = 1; i <= NF; ++i)
                          if (split($i, a, "=") == 2 && a[1] == "KEY_2") {
                              $i = "KEY_2=new value"
                              break
                          } } 1' file
KEY_1=value_1,KEY_2=new value,SOMEKEY=lastValue
    
por 26.09.2018 / 08:41
1

Como mencionado nos comentários, sed não suporta expressões regulares no estilo PCRE (Veja também: Por que minha expressão regular funciona em X, mas não em Y? . Você pode usar perl em vez

$ s='KEY_1=value_1,KEY_2=value_2,SOMEKEY=lastValue'

$ echo "$s" | perl -pe 's/KEY_2=.*?((?=,)|$)/KEY_2=new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue

$ echo "$s" | perl -pe 's/SOMEKEY=.*?((?=,)|$)/SOMEKEY=new_value/'
KEY_1=value_1,KEY_2=value_2,SOMEKEY=new_value

Você pode simplificar o regex:

$ # -l needed to prevent deleting the newline character for last field
$ echo "$s" | perl -lpe 's/KEY_2=\K[^,]+/new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue

$ # to prevent partial match
$ echo "$s" | perl -lpe 's/(?<![^,])KEY_2=\K[^,]+/new_value/'
KEY_1=value_1,KEY_2=new_value,SOMEKEY=lastValue

Veja Opções de comandos perldoc para explicações sobre as opções de linha de comando usadas aqui

    
por 26.09.2018 / 08:44