usando sed com e comercial (&)

19

Estou usando o sed para encontrar e substituir padrões nos arquivos SAS que tenho, em vez de alterá-los individualmente. O problema é que estou tentando substituir variáveis ​​de macro e, quando uso o e comercial, ele não está processando corretamente.

Here's my code:
sed -ie 's/user=&uid./user=&sysuserid./g' *_table_*.sas

sempre que executo esse comando, ele parece acrescentar e fazer todo tipo de coisa divertida com o texto original.

Pergunta: Como substituo o texto que contém e comercial pelo comando sed?

lucasdavis500
fonte
6
&é um caractere especial, portanto, ele precisa ser escapado quando usado no RHS - no seu caso, você precisa executar, 's/user=&uid./user=\&sysuserid./g'embora eu suspeite que você também precise escapar do ponto no LHS para corresponder a um ponto literal e realmente precisar's/user=&uid\./user=\&sysuserid./g'
don_crissti
1
sim, '&' à direita significa basicamente "tudo o que corresponde à esquerda", então escape com '\'. Você deve fazer disso a resposta, em vez de apenas um comentário.
Edward Falk
i did not tem que escapar do primeiro período ... apenas um heads-up em qualquer outra pessoa estava curioso :)
lucasdavis500

Respostas:

25

&é especial no texto de substituição: significa “toda a parte da entrada que foi acompanhado pelo padrão”, então o que você está fazendo aqui substitui user=&uidXcom user=user=&uidXsysuserid.. Para inserir um e comercial real no texto de substituição, use \&.

Outra coisa que parece errada é que, .no padrão de pesquisa, qualquer caractere (exceto uma nova linha), mas .o final do texto de substituição é um ponto literal. Se você deseja substituir apenas a cadeia literal user=&uid., proteja a .barra invertida.

sed -e 's/user=&uid\./user=\&sysuserid./g'

Se você deseja substituir qualquer caractere e preservá-lo no resultado, coloque-o em um grupo e use-o \1na substituição para se referir a esse grupo.

sed -e 's/user=&uid\(.\)/user=\&sysuserid\1/g'

De fato, dada a repetição entre o texto original e a substituição, você deve usar grupos de qualquer maneira:

sed -e 's/\(user=&\)u\(id\.\)/\1sysuser\2/g'

ou seja, "substituir upor sysuserentre user=&e id.".

Gilles 'SO- parar de ser mau'
fonte
você poderia explicar os grupos?
lucasdavis500
2
@ lucasdavis500 Um grupo identifica uma parte do padrão. É delimitado por parênteses de barra invertida. Por exemplo, \(user=&\)é um padrão que corresponde user&e armazena a sequência de correspondência como um grupo (número do grupo 1, pois é o primeiro grupo no padrão). Em seguida, a substituição \1é substituída pela string armazenada para o grupo número 1.
Gilles 'SO- stop be evil'
você quer dizer (usuário = &) armazena usuário = &, não usuário &?
Lucasdavis500
@ lucasdavis500 Não entendi o seu comentário. O caractere =nas expressões regulares e no texto de substituição representa por si só, portanto, user=&corresponde apenas user=&e, user=&no texto de substituição, é user=seguido pela parte da linha correspondida pelo regex.
Gilles 'SO- stop being evil'
1
@ lucasdavis500 O =personagem não tem nenhum significado especial. user=&no texto de substituição produz user=seguido pelo texto correspondente original. user=\&no texto de substituição produzuser=&
Gilles 'SO- stop be evil'