как фильтровать внутренние кавычки?

как фильтровать внутренние кавычки?

можно ли фильтровать, т.е. ставить ESC перед внутренними кавычкамисед,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"и затем вернуться и заменить first на just quote, и заменить final на just quote. Подробное объяснение:

  • 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

Связанный контент