
Eu tenho um arquivo grande que contém caracteres especiais. Há um código de várias linhas que desejo substituir por sed
.
Esse:
text = "\
------ ------\n\n\
This message was automatically generated by email software\n\
The delivery of your message has not been affected.\n\n\
------ ------\n\n"
Precisa se transformar nisso:
text = ""
Tentei o seguinte código, mas sem sorte:
sed -i '/ text = "*/ {N; s/ text = .*affected.\./ text = ""/g}' /etc/exim.conf
Não substitui nada e não exibe nenhuma mensagem de erro
Tenho brincado com ele, mas tudo que tento não funciona.
Responder1
Perl para o resgate:
perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
-i~
irá editar o arquivo "no local", deixando uma cópia de backup-0777
lê o arquivo inteiro de uma vez, não linha por linha
A substituição s///
funciona de forma semelhante ao sed (ou seja, corresponde text = "
seguida por qualquer coisa, exceto aspas duplas, muitas vezes até aspas duplas), mas neste caso, funciona em todo o arquivo.
Responder2
Você tem que verificar o espaço do padrão e continuar puxando a N
linha ext se ela não corresponder, por exemplo
sed '/text = "/{ # if line matches text = "
:b # label b
$!N # pull in the next line (if not the last one)
/"$/!bb # if pattern space doesn't end with " go to label b
s/".*"/""/ # else remove everything between the quotes
}' infile
com gnu sed
você pode escrevê-lo como
sed '/text = "/{:b;$!N;/"$/!bb;s/".*"/""/}' infile
Porém, isso não é muito eficiente, é melhor apenas selecionar o range /text = "/,/"/
, modificar a primeira linha e excluir o resto:
sed '/text = "/,/"/{ # in this range
/text = "/!d # delete all lines not matching text = "
s/\\/"/ # replace the backslash with quotes (this is only
}' infile # executed if the previous d wasn't executed)
novamente, gnu sed
você pode escrevê-lo como uma linha:
sed '/text = "/,/"/{/text = "/!d;s/\\/"/}' infile
Responder3
Pessoalmente, eu faria isso em Perl. Se pudermos assumir que não há "
antes do fechamento "
, você pode fazer:
perl -0pe 's/(text\s*=\s*)".*?"/$1""/s' file
Ele -0
engole o arquivo inteiro, lendo-o na memória. O -p
meio é "imprimir todas as linhas (aqui, uma "linha" será o arquivo inteiro) após aplicar o script fornecido por -e
". O script em si é um operador de substituição simples. Ele irá capturar a string text
seguida por 0 ou mais caracteres de espaço em branco, um =
e 0 ou mais espaços em branco novamente ( text\s*=\s*
) e salvá-la como $1
. Em seguida, ele substituirá o padrão capturado, bem como a string mais curta entre aspas que encontrar, pelo padrão ( $1
) e ""
. A s
bandeira .
combina novas linhas.