Perintah untuk melepaskan string di bash

99

Saya membutuhkan perintah bash yang akan mengubah string menjadi sesuatu yang lolos. Berikut contohnya:

echo "hello\world" | escape | someprog

Mana perintah melarikan diri membuat "hello\world"menjadi "hello\\\world". Kemudian, beberapa katak dapat digunakan "hello\\world"seperti yang diharapkan. Tentu saja, ini adalah contoh sederhana dari apa yang sebenarnya akan saya lakukan.

Pengguna1
sumber
5
Apa sifat pelarian itu? Dengan kata lain, karakter apa yang perlu di-escape? Apakah Anda mencari pelarian gaya C ++ (di mana tab diganti dengan \ t, baris baru dengan \ n, tanda kutip dengan \ ", dll.)? Sulit untuk membantu tanpa masalah didefinisikan dengan baik.
Michael Aaron Safyan
2
kemungkinan duplikasi gema yang lolos dari argumen shell
P Shved
Pertanyaan ini bisa berarti lusinan hal yang berbeda. Alih-alih membuat kami menebak-nebak, akan membantu jika Anda menyatakan dengan tepat jenis pelarian yang Anda cari.
Don Hatch
1
Pertanyaannya khusus untuk menggunakan \\ untuk \. Ada jawaban yang diterima.
Pengguna1

Jawaban:

155

Di Bash:

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

sebagai contoh:

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

Ini juga dapat digunakan melalui variabel:

printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world
Dijeda sampai pemberitahuan lebih lanjut.
sumber
6
Pikiran Anda, %qtelah rusak selama lebih dari satu dekade sampai sekitar tahun 2012. Itu bermasalah ~. Ada juga portabel sed one-liners stackoverflow.com/a/20053121/1073695
Jo Jadi
1
sed memang lebih baik karena bisa lepas dari tanda dolar juga
untore
2
@untore: a='abc$def":'; printf '%q\n' "$a"menghasilkan abc\$def\":(tanda dolar di-escape). Ini Bash 4.3 (Saya mendapat hasil yang sama di Bash 3.2). Versi apa yang Anda gunakan?
Dijeda sampai pemberitahuan lebih lanjut.
3
untuk menghindari tanda dolar, cukup gunakan tanda kutip tunggal, misalnya:printf "%q" 'he$l&lo\world'
LeandroCR
bash printf '%q\n' textmengutip teks dalam bashformat (dan untuk lokal saat ini), jadi itu hanya akan bekerja dalam kasus OP jika mereka someprogmemiliki sintaks kutipan yang sama persis seperti bashyang sangat tidak mungkin.
Stephane Chazelas
9

Pure Bash, gunakan substitusi parameter:

string="Hello\ world"
echo ${string//\\/\\\\} | someprog
Fritz G. Mehner
sumber
1
dengan cara ini "hello world" tidak di-escape ke "hello \ world" - pendekatan printf dalam jawaban yang diterima melakukan itu.
vchrizz
1
Selain itu, "% q" tidak keluar dari '/' seperti dalam "03/25/2017" yang saya perlukan untuk di-escape ke "03 \ / 25 \ / 2017" (sehingga bisa menjadi '/' regular delimited ekspresi).
wrlee
0

Anda dapat menggunakan perl untuk mengganti berbagai karakter, misalnya:

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

Bergantung pada sifat pelarian Anda, Anda dapat menghubungkan beberapa panggilan untuk keluar dari karakter yang tepat.

Michael Aaron Safyan
sumber
1
Kenapa tidak sed? $ echo "hello \ world" | sed 's / \\ / \\\\ /'
Spasi
1
@Octopus, itu juga opsi yang valid. Kebetulan saya lebih nyaman dengan perl, tapi ya, itu juga berhasil.
Michael Aaron Safyan