Comando para escapar de uma string em bash

99

Preciso de um comando bash que converterá uma string em algo que tenha escape. Aqui está um exemplo:

echo "hello\world" | escape | someprog

Onde o comando escape "hello\world"entra "hello\\\world". Então, someprog pode usar "hello\\world"conforme o esperado. Claro, este é um exemplo simplificado do que realmente estarei fazendo.

Usuário1
fonte
5
Qual é a natureza da fuga? Em outras palavras, quais caracteres precisam ser escapados? Você está procurando um escape no estilo C ++ (onde as guias são substituídas por \ t, novas linhas por \ n, aspas por \ ", etc.)? É difícil ajudar sem que o problema esteja bem definido.
Michael Aaron Safyan
2
possível duplicata de echo que o shell escapa de argumentos
P Apresentado
Esta pergunta pode significar uma dúzia de coisas diferentes. Em vez de nos fazer adivinhar, ajudaria se você dissesse exatamente que tipo de fuga está procurando.
Don Hatch
1
A questão era específica para usar \\ para \. Existe uma resposta aceita.
Usuário1

Respostas:

155

No Bash:

printf "%q" "hello\world" | someprog

por exemplo:

printf "%q" "hello\world"
hello\\world

Isso também pode ser usado por meio de variáveis:

printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world
Pausado até novo aviso.
fonte
6
Veja bem, %qesteve quebrado por mais de uma década até cerca de 2012. Teve problemas com ~. Também há sed one-liners portáteis stackoverflow.com/a/20053121/1073695
Jo So
1
sed é de fato melhor porque pode escapar dos cifrões também
descompactar
2
@untore: a='abc$def":'; printf '%q\n' "$a"resulta em abc\$def\":(o cifrão tem escape). Este é o Bash 4.3 (obtive o mesmo resultado no Bash 3.2). Qual versão você está usando?
Pausado até novo aviso.
3
para escapar do cifrão, basta usar aspas simples, por exemplo:printf "%q" 'he$l&lo\world'
LeandroCR
O bash's printf '%q\n' textcita o texto no bashformato (e para a localidade atual), de modo que só funcionaria no caso do OP se eles someprogtivessem exatamente a mesma sintaxe de citação bashque é altamente improvável.
Stephane Chazelas
9

Pure Bash, use a substituição de parâmetro:

string="Hello\ world"
echo ${string//\\/\\\\} | someprog
Fritz G. Mehner
fonte
1
desta forma, "hello world" não é escapado para "hello \ world" - uma abordagem printf na resposta aceita faz isso.
vchrizz
1
Além disso, "% q" não escapa '/' como em "25/03/2017" do qual eu precisava escapar para "25/03 \ / 2017" (de modo que pudesse estar em um regular delimitado por '/' expressão).
wrlee
0

Você pode usar perl para substituir vários caracteres, por exemplo:

$ echo "Hello\ world" | perl -pe 's/\\/\\\\/g'
Hello\\ world

Dependendo da natureza de sua fuga, você pode encadear várias chamadas para escapar dos caracteres adequados.

Michael Aaron Safyan
fonte
1
Por que não sed? $ echo "hello \ world" | sed 's / \\ / \\\\ /'
Espaço
1
@Octopus, essa também é uma opção válida. Acontece que estou mais confortável com o perl, mas sim, isso também funciona.
Michael Aaron Safyan