Команда для экранирования строки в bash

99

Мне нужна команда bash, которая преобразует строку во что-то экранированное. Вот пример:

echo "hello\world" | escape | someprog

Если команда побег делает "hello\world"в "hello\\\world". Затем someprog может использовать "hello\\world"как ожидает. Конечно, это упрощенный пример того, чем я действительно буду заниматься.

Пользователь1
источник
5
Каков характер побега? Другими словами, какие символы нужно экранировать? Вы ищете экранирование в стиле C ++ (где табуляции заменены на \ t, новые строки на \ n, кавычки на \ "и т. Д.)? Трудно помочь, если проблема не будет четко определена.
Майкл Аарон Сафьян
Этот вопрос может означать любую из дюжины разных вещей. Вместо того, чтобы заставлять нас гадать, было бы полезно, если бы вы точно указали, какой вид побега вы ищете.
Don Hatch
1
Вопрос касался использования \\ for \. Есть принятый ответ.
User1

Ответы:

155

В Баше:

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

например:

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

Это также можно использовать через переменные:

printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world
Приостановлено до дальнейшего уведомления.
источник
6
Имейте в виду, он %qбыл сломан более десяти лет, примерно до 2012 года. У него были проблемы с ~. Есть также переносные однострочные sed stackoverflow.com/a/20053121/1073695
Jo So
1
sed действительно лучше, потому что он также может избежать знаков доллара
untore
2
@untore: a='abc$def":'; printf '%q\n' "$a"приводит к abc\$def\":(знак доллара экранирован). Это Bash 4.3 (я получил тот же результат в Bash 3.2). Какую версию ты используешь?
Приостановлено до дальнейшего уведомления.
3
чтобы избежать знака доллара, используйте одинарные кавычки, например:printf "%q" 'he$l&lo\world'
LeandroCR
bash printf '%q\n' textцитирует текст в bashформате (и для текущей локали), так что это будет работать только в случае OP, если у someprogних будет точно такой же синтаксис цитирования, bashчто и маловероятно.
Стефан
9

Чистый Bash, используйте подстановку параметров:

string="Hello\ world"
echo ${string//\\/\\\\} | someprog
Фриц Г. Менер
источник
1
таким образом "hello world" не экранируется в "hello \ world" - это делает printf aproach в принятом ответе.
vchrizz
1
Кроме того, "% q" не экранирует '/', как в "25.03.2017", которое мне нужно было экранировать до "25.03.2017" (чтобы он мог быть в обычном выражение).
wrlee
0

Вы можете использовать perl для замены различных символов, например:

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

В зависимости от характера вашего побега вы можете объединить несколько вызовов, чтобы избежать нужных символов.

Михаил Аарон Сафян
источник
1
Почему не sed? $ echo "hello \ world" | sed 's / \\ / \\\\ /'
Космос,
1
@Octopus, это тоже допустимый вариант. Я чувствую себя более комфортно с perl, но да, это тоже работает.
Майкл Аарон Сафян