2010-09-30 208 views
147

任何人都可以告訴我如何在bash中雙字符串內部雙引號轉義?如何擺脫雙引號內的雙引號?

舉例來說,在我的shell腳本

#!/bin/bash 

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

我不能讓用雙引號逃逸ENCLOSED BY \"正確。我不能爲我的變量使用單引號,因爲我想使用變量$dbtable

+45

你應該熟悉[SQL注入](HTTP的概念:// EN。 wikipedia.org/wiki/SQL_injection),然後再開始編寫這樣的代碼。 – Daenyth 2010-09-30 21:10:22

+1

另請參閱http://mywiki.wooledge.org/BashFAQ/050 – 2013-11-13 13:38:25

+0

[單引號字符串內轉義單引號]的可能重複(http://stackoverflow.com/questions/1250079/escaping-single-quotes-單引號內的字符串) – kenorb 2015-02-28 20:50:54

回答

170

使用反斜線:

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

不工作。 'X = LS; if [-f「$(which」\「」$ x「\」「)」];那麼回聲存在;否則回聲破碎; fi;'給破了,而'... [-f「$(which $ x)」]; ...'或'... [-f $(其中「$ x」)]; ......工作很好。當'$ x'或'$(其中「$ x」)'給出任何空格或其他特殊字符的結果時都會出現問題。解決方法是使用一個變量來保存'which'的結果,但是bash真的無法逃避報價或者我做錯了什麼? – Luc 2015-07-27 15:10:50

+0

我試圖使用下面的'grep -oh「\」\「」$ counter「\」「\ w *」'作爲bash語法的一部分,其中'$ counter'是一個變量。它不喜歡它的任何想法 – 2015-12-18 00:30:39

10

退房的printf ...

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

沒有用printf

echo -e $mystr 

輸出:說 「嗨」

使用的printf

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

輸出:說\ 「喜\」

+1

請注意,'printf'也會轉義更多字符,例如'''','('和')' – 2013-05-10 10:14:21

+0

'printf%q'生成準備用於'eval'的字符串,未格式化爲'echo -e'。 – 2013-11-13 13:38:00

+2

沒有理由將[printf]封裝成[無用的'echo'](http://www.iki.fi/era/unix/award.html#echo)。你的兩個例子都被打破了引用。正確的解決方法是雙引號變量。 – tripleee 2017-03-16 06:33:21

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''「 ''}'「,試圖用雙引號括住單詞key和值,但是在這兩種情況下,我都得到了{key:value} – 2017-06-18 09:28:44

17

擊可以讓你把相鄰的字符串,他們會剛剛結束了被粘在一起。

因此,這:

$ echo "Hello"', world!' 

產生

Hello, world! 

訣竅是根據需要單和雙引號字符串之間交替。不幸的是,它很快變得非常混亂。例如:

$ echo "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引號標註。下面將不會在bash工作 - 它只是爲了說明:

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

上面的「''」等引號將被bash解釋。像" '這樣的引號最終會出現在結果變量中。

如果我給同等待遇,以前面的例子,它看起來像這樣:

$ echoI like to use"double quotes"sometimes

3

。利用$ 「字符串」 的。

在這個例子中,那將是,

dbload = $ 「負荷數據本地的infile \」 'gfpoint.csv' \」到TERMINATED BY表$ DBTABLE場 '' ENCLOSED BY「\」 'LINES TERMINATED BY \ 「 '\ n' \」 忽略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:你爲什麼在'bash'問題上發佈'csh'答案?這兩者完全不同並且不兼容。 – tripleee 2017-03-16 06:35:36

20

我不知道爲什麼這個老問題今天突然出現在bash的標籤列表,但以防萬一對未來的研究人員,請記住,您可以通過使用需要回顯的字符的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因爲它解決了爲〜/ .profile添加PS1變量的問題 'echo'export PS1 ='\ [\ 033 [00; 31m \] $ {?## 0} $([$? -01 0] && echo \ x22 \ x22)\ [\ 033 [00; 32m \] \ u \ [\ 033 [00; \] @ \ [\ 033 [00; 36m \] \ h \ [\ \ [0; 0] [\ 0 [0; 0] [\ 033 [00m \] $( [$ {EUID} -ne 0] && echo \ x22 $ \ x22 || echo \ x22#\ x22)''〜〜/ .profile' – 2017-04-18 05:19:12

+2

這應該可能被標記爲答案。 – qodeninja 2017-12-21 18:27:23

3

商店雙引號字符作爲變量:

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

輸出:

 
Double quotes "X" inside a double quoted string