Bash convertendo nomes de caminho para o sed para que ele escape [duplicado]

3
    

Esta pergunta já tem uma resposta aqui:

    

Estou tendo um problema com um script. Destina-se a alterar um valor em um arquivo chamado %DIR% para que ele se torne um nome de caminho. O problema é as barras no nome do diretório chat o sed, então eu recebo erros estranhos. Preciso converter as barras no nome do caminho em barras de escape.

Portanto, /var/www se tornaria \/var\/www

Mas eu não sei como fazer isso.

Atualmente, o script é executado com:

sed -i "s/%DIR%/$directory/g" "$config"
    
por John Tate 23.02.2016 / 18:08

4 respostas

10

Como você diz que está usando o Bash, pode usar Expansão de Parâmetros para inserir as barras:

$ directory=/var/www
$ echo "${directory//\//\/}"
\/var\/www

Isso é dividido como

  • substitua directory
  • substituindo cada ( // )
  • barra ( \/ )
  • com ( / )
  • barra invertida + barra ( \/ ).

Colocar isso no seu comando sed dá:

sed -i "s/%DIR%/${directory//\//\/}/g" "$config"
    
por 23.02.2016 / 18:14
3

Use a expansão / substituição de parâmetros:

${directory////\/}

Explicação

${directory // / / \/}
            ^  ^ ^  ^
            |  | |  |
            |  | |  replacement, backslash needs to be backslashed
            |  | delimiter
            |  string
        global
      substitution
    
por 23.02.2016 / 18:12
2

Você pode usar os recursos de manipulação de strings do bash fornecidos pela expansão de parâmetros , especificamente a forma ${VARIABLE//PATTERN/REPLACEMENT} . Tenha em mente que / não é o único caractere que precisa ser substituído: em uma substituição s , os caracteres \ , & , newline e s separator precisam ser prefixados com uma barra invertida .

replacement=$directory
replacement=${replacement//\/\\}
replacement=${replacement//\//\/}
replacement=${replacement//&/\&}
replacement=${replacement//$'\n'/\$'\n'}
sed -i "s/%DIR%/$replacement/g" -- "$config"

Como alternativa, use uma ferramenta que não requeira tais citações, como awk ou Perl.

directory=$directory awk '{gsub(/%DIR%/, ENVIRON["directory"])} 1' <"$config" >"$config.new" &&
mv -- "$config.new" "$config"

ou

directory=$directory perl -i -pe 's/%DIR%/$ENV{directory}/g' "$config"
    
por 24.02.2016 / 02:06
1

As outras respostas aqui já são ótimas, mas eu só queria acrescentar que você pode usar um delimitador diferente além de / com sed . Eu faço isso sempre que preciso operar na entrada que contém / :

sed -i "s@%DIR%@${directory}@g" "$config"

Ou até mesmo:

sed -i "s#%DIR%#${directory}#g" "$config"

É tudo a mesma coisa para sed ; ele usará qualquer caractere que você especificar após o s como delimitador.

    
por 24.02.2016 / 22:19