
是否可以進行過濾,即將 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