2013-10-24 66 views
2

我想除去所有雙引號,除非它們已被轉義!替換未使用sed轉義的雙引號

我的示例如下:

The quick brown fox "jumps", over the 'lazy \"dog\"' 

我想達到以下結果:

The quick brown fox jumps, over the 'lazy \"dog\"' 

所以車費我有下面的命令,但它不工作。

sed -i '/^\/\"/! s/"//g' test.sql 

我該如何寫一個sed命令來實現我的目標?

祺金

+1

如何逃逸的定義?是'\\''反斜槓後跟一個轉義引號還是一個反斜槓後跟一個未轉義的引號? –

回答

1

這可以是一個選項:

$ sed -r 's#([^\])"#\1#g' a 
The quick brown fox jumps, over the 'lazy \"dog\"' 

從基本sed 's#something#change#g',它會尋找任何something different than \ + "並將其刪除。它還捕獲該字符((something))並將其打印回(\1)。

對於邊緣情況下,如described by jthill

一對夫婦角落的情況下,-e 'S/「」 * /「/ G' 的主要原因之一來處理連續 報價之前和-es/^」 //處理最初的引號。

$ cat a 
The quick brown fox "jumps", over the 'lazy \"dog\"' 
"The quick brown fox "jumps", over the 'lazy \"dog\"'"" 
$ sed -re 's/""*/"/g' -e 's/^"//' -e 's#([^\])"#\1#g' a 
The quick brown fox jumps, over the 'lazy \"dog\"' 
The quick brown fox jumps, over the 'lazy \"dog\"' 
+0

有沒有辦法避免失去fox和跳轉之間的空間?跳轉中的s也被刪除。 –

+0

是的!看到我更新的答案,@ KimA.Jakobsen – fedorqui

+1

在處理連續引號和'-es/^「//'來處理初始值之前的幾個角落情況下,'-e's /」「* /」/ g'引號。 – jthill

1

awk版本(不做到這一點的最好辦法)

awk '{gsub(/\\\"/,"_#_");gsub(/\"/,x);gsub(/_#_/,"\\\"")}1' 
The quick brown fox jumps, over the 'lazy \"dog\"' 

這取代\"_#_(這需要有一些獨特的)
然後取出單"並更改回\"


一個不太便攜GNU awk version

awk '{print gensub(/([^\\])\"/, "\\1", "g")}' 
The quick brown fox jumps, over the 'lazy \"dog\"' 

一個好的awk版本(便攜式):

awk '{gsub(/[^\\]"/,"&_");gsub(/"_/,x)}1' 

最佳awk版本至今(便攜式):

awk '{ORS=(/\\$/?RS:x)}1' RS=\" 
+0

增加了一個很好的'awk'版本,它使用'ORS' – Jotne

0

POSIX上使用臨時替代(此處炭#)sed的

sed 's/#/#a/g;s/\\"/#b/g;s/"//g;s/#b/\\"/g;s/#a/#/g' File.ext