2010-09-30 2 views
147

Может ли кто-нибудь показать мне, как избежать двойной кавычки внутри двойной строки в bash?Как избежать двойной цитаты внутри двойных кавычек?

Например, в моем сценарии оболочки

#!/bin/bash 

dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES" 

я не могу получить прилагаемую BY \" с двойной цитатой побеге правильно. Я не могу использовать одиночную кавычку для моей переменной, потому что хочу использовать переменную $dbtable.

+45

Вы должны ознакомиться с концепцией [инъекции SQL] (HTTP: // эн. wikipedia.org/wiki/SQL_injection), прежде чем вы начнете писать такой код. – Daenyth

+1

Также см. Http://mywiki.wooledge.org/BashFAQ/050 –

+0

возможный дубликат [Экранирование одиночных кавычек в строках с одним кавычком] (http://stackoverflow.com/questions/1250079/escaping-single-quotes- внутри-одиночных кавычек) – kenorb

ответ

170

Используйте обратную косую черту:

echo "\""  # Prints one " character. 
+3

Не работает. 'Х = Ls; если [-f "$ (который" \ "" $ x "\" ")"]; то эхо существует; иначе эхо сломан; fi; 'дает сломанные, тогда как' ... [-f "$ (which $ x)"]; ... 'или' ... [-f $ (который «$ x»)]; ... 'отлично работает. Проблемы возникнут, когда либо '$ x', либо результат' $ (который «$ x») 'дает что-либо с пробелом или другим специальным символом. Обходной путь использует переменную для хранения результата 'which', но bash действительно неспособна избежать цитаты, или я делаю что-то неправильно? – Luc

+0

Я пытаюсь использовать следующий 'grep -oh '\" \ "" $ counter "\" "\ w *" 'как часть синтаксиса bash, где в' $ counter' есть переменная. ему не нравятся мысли –

10

чек из PRINTF ...

#!/bin/bash 
mystr="say \"hi\"" 

Без использования PRINTF

echo -e $mystr 

выход: сказать "привет"

Использование PRINTF

echo -e $(printf '%q' $mystr) 

выход: говорят \ "Привет \"

+1

Обратите внимание, что 'printf' вытесняет больше символов, например' '', '(' и ')' –

+0

'printf% q' генерирует строки, готовые для' eval', не отформатированные для 'echo -e'. –

+2

Нет никакой причины, чтобы обернуть 'printf' [бесполезным использованием' echo'] (http://www.iki.fi/era/unix/award.html#echo). Оба примера прервали цитирование. Правильное исправление заключается в двойном кавычке переменной. – tripleee

35

Простой пример побега котировки в оболочке:

$ echo 'abc'\''abc' 
abc'abc 
$ echo "abc"\""abc" 
abc"abc 

Это сделано по отделочный уже открыл один ('), (\'), затем открывается еще один (').

В качестве альтернативы:

$ echo 'abc'"'"'abc' 
abc'abc 
$ echo "abc"'"'"abc" 
abc"abc 

Это делается отделка уже открыл один ('), размещение цитаты в другой кавычки ("'"), затем открыть еще одну (').

Другие примеры: Escaping single-quotes within single-quoted strings

+1

Я попробовал sh -c "echo '{" key ":" value "}'" и даже sh -c "echo '{' '' '' key ''" '': '' "'' value ''" ''} '', чтобы заключить ключ слова и значение в двойные кавычки, но в обоих случаях я получил {ключ: значение} –

17

Bash позволяет размещать строки смежно, и они просто в конечном итоге склеиваются.

Так что:

$ echo "Hello"', world!' 

производит

Hello, world! 

Хитрость заключается в том, чтобы чередовать между одинарными и двойными кавычками в соответствии с требованиями. К сожалению, он быстро становится очень грязным.Например:

$ echo "I like to use" '"double quotes"' "sometimes" 

производит

I like to use "double quotes" sometimes 

В вашем примере, я хотел бы сделать это что-то вроде этого:

$ dbtable=example 
$ dbload='load data local infile "'"'gfpoint.csv'"'" into '"table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"'"'"' LINES "'TERMINATED BY "'"'\n'"'" IGNORE 1 LINES' 
$ echo $dbload 

, который производит следующий вывод:

load data local infile "'gfpoint.csv'" into table example FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "'\n'" IGNORE 1 LINES 

Это трудно понять, что происходит здесь, но я могу аннотировать его с помощью Unicode кавычки. Ниже не будет работать в Баш - это просто для иллюстрации:

dbload= 'load data local infile " ''gfpoint.csv' "' " into 'table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"' " '' LINES "' TERMINATED BY " ''\n'"' " IGNORE 1 LINES'

Котировки, подобные «'» в приведенном выше, будут интерпретироваться bash. Котировки, такие как " ', попадут в результирующую переменную.

Если я даю такое же лечение в предыдущем примере, это выглядит следующим образом:

$ echo «I like to use» «"double quotes"» «sometimes»

3

Воспользоваться $ «строка».

В этом примере было бы,

DBLoad = $ "загрузка данных локального входной_файл \" 'gfpoint.csv' \»в таблицу $ dbtable ПОЛЕЙ TERMINATED BY '' ЗАКРЫТАЯ BY«\» 'LINES TERMINATED BY \ " '\ п' \" ИГНОРИРУЙТЕ 1 ЛИНИИ»

Примечание (из man page):

в двойных кавычках строка предшествует знак доллара ($ "строка") приведет к тому, что строка будет переведена в соответствии с к текущему языку. Если текущий язык - C или POSIX, знак доллара игнорируется. Если строка переводится и заменяется, замена выполняется двойным образом.

-4

добавить "\", прежде чем двойные кавычки, чтобы избежать его, вместо \

#! /bin/csh -f 

set dbtable = balabala 

set dbload = "load data local infile "\""'gfpoint.csv'"\"" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"\""' LINES TERMINATED BY "\""'\n'"\"" IGNORE 1 LINES" 

echo $dbload 
# load data local infile "'gfpoint.csv'" into table balabala FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "''" IGNORE 1 LINES 
+2

Downvote: Почему вы отправляете ответ 'csh' на вопрос' bash'? Эти две совершенно разные и несовместимые. – tripleee

20

Я не знаю, почему этот старый вопрос появился сегодня в Баш помечено списки, но только в том случае, для будущих исследователей , имейте в виду, что вы можете избежать экранирования, используя коды ascii символов, которые нужно эхо. Пример:

echo -e "this is \x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22"                           
this is "'"'"text"'"'" 

\x22 является кодом ASCII (в шестнадцатеричном) для двойных кавычек и \x27 для одиночных кавычек. Точно так же вы можете повторить любой символ.

Я полагаю, что если мы попытаемся повторить вышеуказанную строку с обратными косыми чертами, мы будем нуждаться в грязном два ряда эха ... управляющие последовательностями :)

Для присваивания значения переменного это эквивалентно:

$ a=$'this is \x22text\x22'                                    
$ echo "$a"                                        
this is "text" 

Если переменная уже установлена ​​другой программой, вы можете применить двойные/одинарные кавычки с sed или аналогичными инструментами. Пример:

$ b="just another text here" 
$ echo "$b" 
just another text here 
$ sed 's/text/"'\0'"/' <<<"$b" #\0 is a special sed operator 
just another "0" here #this is not what i wanted to be 
$ sed 's/text/\x22\x27\0\x27\x22/' <<<"$b" 
just another "'text'" here #now we are talking. You would normally need a dozen of backslashes to achieve the same result in the normal way. 
+0

+1, потому что он решил проблему добавления переменной PS1 в ~/.profile экспорт «echo» PS1 = '\ [\ 033 [00; 31m \] $ {? ## 0} $ ([$? -ne 0] && echo \ x22 \ x22) \ [\ 033 [00; 32m \] \ u \ [\ 033 [00m \] @ \ [\ 033 [00; 36m \] \ h \ [\ 033 [00m \] [\ [\ 033 [01; 33m \] \ d \ t \ [\ 033 [00m \]] \ [\ 033 [01; 34m \] \ w \ n \ [\ 033 [00m \] $ ([$ {EUID} -ne 0] && echo \ x22 $ \ x22 || echo \ x22 # \ x22) '' >> ~/.profile' –

+2

это, вероятно, должно быть отмечено как ответ. – qodeninja

3

магазин двойной кавычки в качестве переменной:

 
dqt='"' 
echo "Double quotes ${dqt}X${dqt} inside a double quoted string" 

Выход:

 
Double quotes "X" inside a double quoted string 
Смежные вопросы