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


99

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

echo "hello\world" | escape | someprog

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


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, но да, это тоже работает.
Майкл Аарон Сафян
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.