2017-07-28 65 views
1

我已經在互聯網上搜索過,並嘗試了很多組合,但似乎無法使其工作。只有在括號內出現轉義字符

我想寫一個腳本來創建LaTeX表代碼。這一切都正常工作,直到我有裏面的一個值的符號,例如,

{1702} & {12389122} & {Topic 1 Online Quiz} & {1.7} & {2} & {83.3} \\\hline 
{1702} & {12389122} & {Topic 2 & 3 Online Q...} & {1.9} & {2} & {93.3} \\\hline 
{1702} & {12389122} & {Topic 4 Online Quiz} & {} & {2} & {} \\\hline 
{1702} & {12389122} & {Topic 5 Online Quiz ...} & {} & {2} & {} \\\hline 

我需要能夠在input.txt的文件讀取包含此數據,然後將結果輸出到output.txt文件與來自在第2行相距相同的數據我需要轉義&符,例如,

{1702} & {12389122} & {Topic 1 Online Quiz} & {1.7} & {2} & {83.3} \\\hline 
{1702} & {12389122} & {Topic 2 \& 3 Online Q...} & {1.9} & {2} & {93.3} \\\hline 
{1702} & {12389122} & {Topic 4 Online Quiz} & {} & {2} & {} \\\hline 
{1702} & {12389122} & {Topic 5 Online Quiz ...} & {} & {2} & {} \\\hline 

但只逃脫該{}

我想可能有之間出現的符號(S)先前接近,但我最後一次嘗試如下:

sed 's/\({[a-zA-Z0-9. _]*\)\(\&\)\([a-zA-Z0-9. _]*}.*\)/\1\\\2\3/' input.txt > output.txt 

任何幫助將不勝感激。

回答

3

在下面的代碼對我的作品

sed 's/{\([^}]*\)&\([^}]*\)}/{\1\\\&\2}/g' input.txt > output.txt 

說明: sed命令的/g標誌執行整個線替換。在沒有/g標誌的情況下,sed每行僅執行第一次替換。

sed命令的「搜索」領域,我開始與{,查找不}&停止所有字符。然後我再次尋找所有不是}的字符,直到我遇到第一個}'. This restricted search ensures that I find & that is strictly within closest {and} . Then I am replacing the same with escaped &`。

注意:這隻會取代一個給定的一對花括號內的一個&。如果您有多個&,則需要修改正則表達式。

+0

您不需要正則表達式的尾部:'sed's/\({[^&}] * \)&/ \ 1 \\\&g'file' –

+0

@EdMorton的確如此。我在正則表達式中添加了尾部,以便在需要在輸入數據中支持多個'&'的情況下,它可以擴展到OP。某些行'sed's/{\([^}] * \)&\([^}] * \)&\([^}] * \)}/{\ 1 \\\&2 \\ &\ 3}/g'input.txt> output.txt' ...等等。 – Prasanna

+0

如果這可能發生,那麼OP應該只使用GNU awk,你可以在while循環中調用gensub()(我確定有一些GNU sed wizardry包含30個單字符和batman符號,你會....)。 –

0

如果perl是好的

$ echo '{1702} & {Topic 2 & 3 Online Q}' | perl -pe 's/\{[^}]+\}/$&=~s|&|\\&|gr/ge' 
{1702} & {Topic 2 \& 3 Online Q} 
$ echo '{1 & 7 & 0 & 2} & {Topic 2 & 3}' | perl -pe 's/\{[^}]+\}/$&=~s|&|\\&|gr/ge' 
{1 \& 7 \& 0 \& 2} & {Topic 2 \& 3} 
  • \{[^}]+\}比賽{其次是非}字符與}
    • 嵌套結束沒有被處理,爲前:{17 {3 & 3} & 02}會給{17 {3 \& 3} & 02}
  • /ge更換所有出現,並允許在替換部中使用Perl代碼
  • $&=~s|&|\\&|gr替換所有&\&僅在匹配的文本


隨着sed,上GNU sed測試,語法可能用於其它實施方式而變化

$ echo '{1 & 7 & 0 & 2} & {Topic 2 & 3}' | sed -E ':a s/(\{[^}]*[^\\])&([^}]*\})/\1\\\&\2/; ta' 
{1 \& 7 \& 0 \& 2} & {Topic 2 \& 3} 
  • :a LA BEL
  • \{[^}]*[^\\]比賽{後跟零個或多個}字符和非\字符
  • &比賽&但如果通過\禮貌[^\\]
  • [^}]*\}剩餘的字符之前,可以跳過我覺得
  • \1\\\&\2會前綴\&
  • ta循環至標籤a直到替換成功