sed caractere especial de substituição não funciona no shell script

2

Eu quero escrever um script 'test.sh' que levará a entrada de um usuário e substituirá todos os caracteres especiais por um '\' + o caractere. Meu script:

#!/bin/bash
echo 'input='"$1"
arg='echo "$1" | sed 's:[]\[\^\$\.\*\/]:\&:g''
echo 'modified input='"$arg"

Meu comando funciona na string 'xy', que não possui caracteres especiais. Eu corro isso no meu terminal:

test.sh xy

E eu obtenho:

input=xy
modified input=xy

No entanto, quando executo isso:

test.sh x.y

Eu recebo:

input=x.y
modified input=x&y

Eu não entendo porque este script não está funcionando. Espero receber:

input=x.y
modified input=x\.y

Acho que o problema está no comando sed, mas não tenho certeza de onde:

sed 's:[]\[\^\$\.\*\/]:\&:g'
    
por drapkin11 07.11.2012 / 21:22

2 respostas

4

Eu não acho que você esteja capturando o grupo corretamente. Tente isso?

sed 's:\([]\[\^\$\.\*\/]\):\:g'

Edit: nevermind, eu não estava ciente da relevância do & O problema é que você precisa extrair as barras extras em substituição por causa da análise e passando para o sub shell.

sed 's:[]\[\^\$\.\*\/]:\\&:g'

Além disso, se você usou $ (comando) em vez de backticks, você não precisa do extra \ 's

    
por 07.11.2012 / 21:35
1

Portanto, a tarefa é escrever uma substituição sed que escapa de todos os caracteres especiais (definidos como os caracteres []^$.*/ e eu adicionei \ também) em uma string.

A substituição pode parecer

s/[][\^$.*/]/\&/g

Note que nós realmente não temos que escapar de nenhum dos caracteres no [...] set (o \ é tratado literalmente também, então nós não podemos escapar de nada lá) , e que a única coisa que temos que ter certeza é que ] está no começo disso.

Assim, o script (reescrito como uma função shell e reformulado de outras formas) torna-se

function escape
{
    printf '%s\n' "$1" | sed 's/[][\^$.*/]/\&/g'
}

Teste:

$ escape 'hello world'
hello world

$  escape '*.*'
\*\.\* 

$ escape '\/'
\\/

$ escape '/\'
\/\

$ escape 's/[][\^$.*/]/\&/g'
s\/\[\]\[\\^\$\.\*\/\]\/\\&\/g
    
por 22.01.2017 / 23:47