LINUX.ORG.RU

addslashes для bash, или экранировать каждый символ в строке

 ,


1

1

Гуру, пожалуйста, помогите.

Как в bash, не прибегая к другим языкам программирования, по заданной строке получить строку, в которой экранирован каждый символ?

Например, по строке

This isn't a [good] file name: "-blah.txt"
получить строку
\T\h\i\s\ \i\s\n\'\t\ \a\ \[\g\o\o\d\]\ \f\i\l\e\ \n\a\m\e\:\ \"\-\b\l\a\h\.\t\x\t\"

Это нужно от того, что в некоторых параметрах стандартных команд (grep, find) заключение строки в одинарные кавычки не лишает специальные символы специального значения. А также это нужно для безопасной передачи таких строк в бд, типа sqlite.

Есть ли что-нибудь стандартное для этого, по примеру addslashes в php? Спасибо за вашу доброту и помощь.

★★★★★

Последнее исправление: record (всего исправлений: 2)

1. экранируют обратным слешем

2. sed

anonymous
()
Ответ на: комментарий от uspen

Спасибо, за printf '%q\n' !

Кажется, то, что нужно.

record ★★★★★
() автор топика

А не боишься, что оно начнёт воспринимать всякие \t, \n и т.д. не как буквы, а как раз как спецсимволы? Странное решение, на мой взгляд.

shell-script ★★★★★
()

Если нет контрольных инъекций - очень сомнительное решение.
Странно.

Spirit_of_Stallman ★★★
()
Ответ на: комментарий от uspen

Есть языковая проблема с printf...

$ printf "%q\n" "good one"
good\ one
$ printf "%q\n" 'что-нибудь по-русски.txt'
$'\321\207\321\202\320\276-\320\275\320\270\320\261\321\203\320\264\321\214 \320\277\320\276-\321\200\321\203\321\201\321\201\320\272\320\270.txt'

$ escaped=$(printf '%q' "яяя я") ; echo "$escaped"
$'\321\217\321\217\321\217 \321\217

$ echo $LANG
ru_RU.utf8

record ★★★★★
() автор топика
Последнее исправление: record (всего исправлений: 7)
$ echo "This isn't a [good] file name: \"-blah.txt\"" |sed 's/./\\&/g'

\T\h\i\s\ \i\s\n\'\t\ \a\ \[\g\o\o\d\]\ \f\i\l\e\ \n\a\m\e\:\ \"\-\b\l\a\h\.\t\x\t\"
tides
()

А также это нужно для безопасной передачи таких строк в бд, типа sqlite.

NoWay

Есть ли что-нибудь стандартное для этого, по примеру addslashes в php?

и быть не может.

Это нужно от того, что в некоторых параметрах стандартных команд (grep, find) заключение строки в одинарные кавычки не лишает специальные символы специального значения.

пример можно?

drBatty ★★
()
Ответ на: комментарий от record

Есть языковая проблема с printf...

это не языковая проблема, %q все спецсимволы переводит, и русские буквы тоже. Они в таком виде даже работают, например

$ ls -l $'\321\204'
-rw-r--r-- 1 drb users 0 марта 15 10:14 ф

drBatty ★★
()
Ответ на: комментарий от drBatty

пример можно?

$ touch "lll [xx yy].txt"
$ ls 'lll [xx yy].txt'
lll [xx yy].txt
$ find -name 'lll [xx yy].txt'
$ find -name 'lll \[xx yy].txt'
./lll [xx yy].txt

record ★★★★★
() автор топика
Ответ на: комментарий от drBatty

ls -l $'\321\204'

Интересно, спасибо.

record ★★★★★
() автор топика
Ответ на: комментарий от drBatty

пример можно?

echo "xxx yyy zzz" > test.txt ; grep 'x.*z' test.txt
record ★★★★★
() автор топика
Последнее исправление: record (всего исправлений: 1)
Ответ на: комментарий от drBatty

это не языковая проблема, %q все спецсимволы переводит,

А что же printf %q латиницу сохраняет, а другие языки нет?

record ★★★★★
() автор топика
Ответ на: комментарий от record

$ find -name 'lll \[xx yy].txt'

ты неправильно понимаешь «лишение специального смысла». Дело в том, что строка парсится дважды: сначала bash'ем, а потом уже твоей утилитой. А вот для find -name символ [ имеет специальный смысл, хоть и означает тоже самое, что и в bash. Т.е. спец-значения он лишается только для bash, а в find - не лишается.

Потому-то и noway, ибо твоя утилита сначала распарсить find, а потом экранировать дважды.

Вот так:

$ find -name lll\ \\\[xx\ yy\\\].txt
./lll [xx yy].txt
тут пробелы экранируются один раз, потом экранируются слеши и [, дабы дойти до find, и там они экранируются ещё раз, дабы войти в find как обычные символы.

drBatty ★★
()
Ответ на: комментарий от record

А что же printf %q латиницу сохраняет, а другие языки нет?

потому-что нелатиница не является «обычными символами». ЕМНИП «обычные символы» это вообще только [a-zA-Z0-9_]. Ну как в логине, или в имени переменной C/C++ (там ещё есть дополнительное условие, что первый символ не цифра и не _)

drBatty ★★
()
Ответ на: комментарий от drBatty

Надо же, как интересно:

$ python -c "import re;print(re.match(r'\w+\W\w+','др батя'))"
<_sre.SRE_Match object at 0x01A691A8>

$ python -c "import re;print(re.match(r'\w+\W\w+','дрбатя'))"
None

anonymous
()
Ответ на: комментарий от anonymous

Да у тебя же бухурт.

кого и с кем?

Как так, легаси хлам и не поддерживает юникод?

ты вообще про что сейчас? УМВР.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.