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.


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


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

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

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.