como filtrar aspas internas?

como filtrar aspas internas?

é possível filtrar, ou seja, colocar ESC na frente das aspas internas comsed,estranhoou outra ferramenta *NIX (sem Perl/python)?

Exemplo (revisado):

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

rótulo="123 \"456\" 789" "AB C"

Em outras palavras, é necessário um filtro que filtre da seguinte maneira: o primeiro e o último"char será passado como está, mas todos os outros"será substituído por\seguido pela".

Responder1

Com GNU sed, que suportasubstituindo todas as ocorrências de uma contagem específica

$ 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

Todos "(espere primeiro ") são substituídos \"e depois \removidos do último\"


Se GNU sednão estiver disponível, remova \primeiro \"também

$ 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

Nota: Algumas sedversões podem precisar -rem vez de-E


Comperl

$ 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

Aqui, a string até o primeiro "e a string do último "ao final da linha sãoignoradoenquanto os restantes "são substituídos por\"

Responder2

sedpara o resgate.

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

Substitua todas as aspas por ESC"e, em seguida, revisite e substitua primeiro por apenas aspas e substitua final por apenas aspas. Explicação detalhada:

  • s/"/\x1b"/g: substitua todos os caracteres de aspas por \x1b (ESC) e aspas.

  • s/\x1b"/"/: substitua primeiro \x1b (ESC) e combinação de aspas por aspas simples.

  • s/\(.*\)\x1b"/\1"/: substitua final \x1b (ESC) e combinação de aspas por aspas simples

Exemplo de saída:

$ 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
$

Responder3

Existe uma maneira de obter o que você pede em várias etapas:
Supondo que uma variável possa conter a string (a string não possui aspas simples):

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

Poderíamos cortar a parte após \":

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

Em seguida, remova até o primeiro \":

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

Substitua tudo \"por \e":

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

E finalmente, reconstrua a string original e use printf para os escapes:

$ 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

informação relacionada