
é 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 sed
nã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 sed
versões podem precisar -r
em 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
sed
para 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