如何過濾內引號?

如何過濾內引號?

是否可以進行過濾,即將 ESC 放在內部引號前面sed,awk或其他 *NIX 工具(沒有 perl/python)?

範例(已修改):

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | magic-filter
label="123 \"456\" 789\" \"AB C" e f gh

標籤=“123\”456\“789”“AB C”

換句話說,需要一個過濾器,它將按以下方式過濾:第一個和最後一個char 將按原樣傳遞,但所有其他將被替換為\其次是

答案1

GNU sed,支持取代特定計數中的所有出現次數

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | 
    sed -E 's/"/\\"/2g; s/\\("[^"]*)$/\1/'
label="123 \"456\" 789\" \"AB C" e f gh

所有"(除了第一個")都被替換為\",然後\從最後一個中刪除\"


如果GNU sed不可用,也\從第一個中刪除\"

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | 
    sed -E 's/"/\\"/g; s/\\"/"/; s/\\("[^"]*)$/\1/'
label="123 \"456\" 789\" \"AB C" e f gh

注意:某些sed版本可能需要-r而不是-E


perl

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh | 
    perl -pe 's/(^[^"]*"|"[^"]*$)(*SKIP)(*F)|"/\\"/g'
label="123 \"456\" 789\" \"AB C" e f gh

這裡,從第一個開始的字串"和從最後一個"到行尾的字串是跳過而其餘的則"替換為\"

答案2

sed來救援。

sed 's/"/\x1b"/g;s/\x1b"/"/;s/\(.*\)\x1b"/\1"/'

將所有引號替換為ESC"然後重新訪問並用僅引用替換第一個,並用僅引用替換最後一個。詳細解說:

  • s/"/\x1b"/g:將所有引號字元替換為 \x1b (ESC) 和引號。

  • s/\x1b"/"/:將第一個 \x1b (ESC) 和引號組合替換為單引號。

  • s/\(.*\)\x1b"/\1"/:用單引號取代最後的 \x1b (ESC) 和引號組合

輸出範例:

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh |sed 's/"/\x1b"/g;s/\x1b"/"/;s/\(.*\)\x1b"/\1"/'|od -c
0000000   l   a   b   e   l   =   "   1   2   3     033   "   4   5   6
0000020 033   "       7   8   9 033   "     033   "   A   B       C   "
0000040       e       f       g   h  \n
0000050
$

答案3

有一種方法可以透過幾個步驟獲得您所要求的內容:
假設變數可以包含字串(該字串沒有單引號):

$ label='label=\"123 \"456\" 789\" \"AB C\" e f gh'

我們可以砍掉後面的部分\"

$ front=${label%\\\"*}
$ echo "$front"
\"123 \"456\" 789\" \"AB C

然後刪除直到第一個\"

$ mid=${front#*\"}
$ echo "$mid"
123 \"456\" 789\" \"AB C

全部替換\"\e"

$ final=${mid//\\\"/\\e}
$ echo "$final"
123 \e456\e 789\e \eAB C

最後,重建原始字串並使用 printf 進行轉義:

$ printf "label=\"${front%%\\\"*}$final\"${label#"${front}"}\n"
label="123 456 789 AB C"" e f gh

$ printf "label=\"${front%%\\\"*}$final\"${label#"${front}"}\n" | od -vAn -t x1c
  6c  61  62  65  6c  3d  22  31  32  33  20  1b  22  34  35  36
   l   a   b   e   l   =   "   1   2   3     033   "   4   5   6
  1b  22  20  37  38  39  1b  22  20  1b  22  41  42  20  43  22
 033   "       7   8   9 033   "     033   "   A   B       C   "
  22  20  65  20  66  20  67  68  0a
   "       e       f       g   h  \n

相關內容