Por que regex com \\ $ \ {trabalha com egrep, mas não com sed?

1

Dado um texto como este

./RFF_09 -f${FILE} -c${COND}

dentro de um arquivo, este comando egrep corresponderá corretamente:

egrep './RFF(.*) (.*)-c\$\{COND\}' file

mas este comando sed não irá

sed -n "s:'./RFF(.*) (.*)-c\$\{COND\}':./RFF$1 $2-cRFF$1:gp"

Ele falhará com sed: -e expression #1, char 38: invalid content of \{\} . Eu também tentei com

sed -n "s:'./RFF(.*) (.*)-c\$\{COND\}':DUMMY:gp" file
sed -n s:'./RFF(.*) (.*)-c\$\{COND\}':DUMMY:gp file

com o mesmo resultado.

sed -n "s:'./RFF(.*) (.*)-c\$\{COND\}':DUMMY:gp" file

Não me dará uma mensagem de erro, mas não corresponderá.

O que estou fazendo de errado? Ou melhor: como posso substituir o texto conforme sugerido pelo comando original? Eu estou usando versões bastante antigas do sed (4.1.2) e egrep (2.5.1), portanto, uma solução alternativa é apreciada mesmo se você não puder reproduzir o erro com versões mais recentes.

    
por Chaos_99 28.01.2015 / 16:34

2 respostas

2

Se você usa o e grep que significa grep com a sintaxe estendida do regexp, então para poder transferir seu padrão para o sed você precisa adicionar parametr -r(--regexp-extended) ou -E em algumas versões.

Em relação à sua expressão, você tem \ extra depois de c , por isso, mesmo com o egrep, não corresponde a

Além disso, use melhor em vez de $1 para correspondência inversa.

Assim, o comando final poderia ser:

sed -rn 's:\./(RFF.*)( .* -c)\$\{COND\}:./:gp'

Ou

sed -rn 's:(\./(RFF\S*) \S* -c)\$\{COND\}::gp'
    
por 28.01.2015 / 17:39
2

Em sua declaração original, o problema é que você está misturando citações sintáticas e literais : as aspas simples entre aspas duplas ser combinado literalmente. Você vai querer simplesmente removê-los ou misturar aspas ( não aninha-os). Exemplos não testados:

sed 's/foo/{bar}/'
sed "s/foo/"'{bar}'"/"

Existem muitos sabores de expressões regulares , e todos eles suportam uma sintaxe diferente. Na tentativa de usar apenas aspas simples, o problema é o sabor da regex: sed usa \{N\} para as contagens de correspondência, portanto, N precisa ser um número inteiro. Você vai querer usar {COND} .

(Na verdade, usar um regex para resolver um problema agora significa que você tem dois problemas. E fazer praticamente qualquer coisa complexa no código shell significa ter N problemas, sendo N pelo menos tão grande quanto o número de linhas.)

    
por 28.01.2015 / 16:44