como filtrar citações internas? [fechadas]

1

é possível filtrar, ou seja, colocar ESC na frente das aspas internas com sed , awk ou 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

label="123 \" 456 \ "789" "AB C"

Em outras palavras, é necessário um filtro que será filtrado da seguinte maneira: o primeiro e o último caracter " será transmitido como está, mas todos os outros " serão substituídos por \ seguido por ".

    
por ivand58 23.10.2016 / 20:31

3 respostas

1

Com GNU sed , que suporta substituição de todas as ocorrências de contagem particular

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

Todos " (espera primeiro " ) são substituídos por \" e, em seguida, \ é removido do último \"


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

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

Observação: algumas versões sed podem precisar de -r em vez de -E


Com 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

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

    
por 24.10.2016 / 07:33
1

sed para o resgate.

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

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

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

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

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

Exemplo de saída:

$ echo label=\"123 \"456\" 789\" \"AB C\" e f gh |sed 's/"/\x1b"/g;s/\x1b"/"/;s/\(.*\)\x1b"/"/'|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
$
    
por 23.10.2016 / 20:41
0

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

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

Poderíamos cortar a parte depois do \" :

$ 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 todos os \" por \e" :

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

E, finalmente, reconstrua a string original e use printf para as fugas:

$ 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
    
por 23.10.2016 / 21:59