Como substituir aspas em um arquivo pelo sed?

10

Eu tenho um arquivo que contém várias linhas de xml. Gostaria de substituir certas partes do arquivo. Algumas partes do arquivo contêm aspas ( ") que eu gostaria de substituir. Eu tenho tentado escapar das aspas com \, mas não acho que isso esteja funcionando com base no resultado do meu arquivo.

Aqui está um exemplo de um dos meus comandos sed:

sed -e "s/\"text\"/'text'/ig" file.xml > temp.tmp

É assim que você escapa aspas em um comando sed ou estou fazendo algo errado?

jbranchaud
fonte
2
Seu comando parece correto para substituir "text"por 'text'. Claro que não fará nada para "othertext". Mostre algumas linhas de entrada, a saída indesejada correspondente e explique qual saída você deseja.
Gilles 'SO- stop be evil'
Então, \"é a maneira correta de escapar aspas no comando sed?
jbranchaud
4
Não é para sed: sed não precisa, nem suporta, de escapar ". Mas seu comando shell usa uma cadeia de caracteres entre aspas duplas e \"está correto lá. O sedprograma vê s/"text"/'text'/igcomo argumento para -e.
Gilles 'SO- stop be evil'
@Gilles E quanto aos espaços? O sed entende e respeita os espaços em branco? Por exemplo, se meu comando contivesse s/\"text\" /'text'/ig, encontraria apenas "text" o espaço após ele?
Jbranchaud
3
Os espaços devem corresponder exatamente. Em vez de continuar esse diálogo, recomendo que você publique algumas entradas de amostra e a saída desejada correspondente (e talvez explique por que você precisa alterar a citação). Não está claro se sedé a ferramenta certa para o trabalho, talvez você queira um analisador XML.
Gilles 'SO- stop be evil'

Respostas:

11

Duas dicas:

  1. Você não pode escapar de uma única citação dentro de uma sequência entre aspas simples. Portanto, você deve fechar a cotação, adicionar uma cotação de escape e abrir as aspas novamente. Ou seja 'foo'\''bar':, que se divide em:

    • 'foo'        citado foo
    • \'             escapou '
    • 'bar'        citado bar

    cedendo foo'bar.

  2. (opcional) Você não precisa necessariamente usar o /sed. Acho que usar /e \na mesma expressão sed torna difícil de ler.

Por exemplo, para remover as aspas deste arquivo:

$ cat /tmp/f
aaa"bbb"'ccc'aaa

Dadas minhas duas dicas acima, o comando que você pode usar para remover aspas duplas e simples é:

$ sed -e 's|["'\'']||g'  /tmp/f

Com base na minha primeira dica, o shell reduz o segundo argumento do sed (ou seja, a sequência após a -e) s|["']||ge passa a sequência para sed. Com base na minha segunda dica, sed trata da mesma forma que s/['"]//g. Isso significa

remova todos os caracteres correspondentes 'ou "   ( ou seja, substitua-os por nada)

Você provavelmente precisa de algo mais complexo do que isso para fazer o que deseja, mas é um começo.

Yves Junqueira
fonte
11
Para enfatizar sua segunda dica: você pode usar qualquer caractere no lugar de / ao usar os comandos s e y, possivelmente entre outros. Ao usar regexps com outros comandos sed, o primeiro delimitador (se estiver usando uma alternativa a /) deve ser escapado. Seu delimitador preferido também deve ser escapado se você estiver tentando correspondê-lo na regexp.
precisa
É difícil misturar aspas simples e aspas duplas sem ficar bagunçado. Algumas pessoas acham mais fácil ler se você citar aspas simples, colocando-as entre aspas duplas, em vez de escapar delas. Então, em vez de 'foo'\''bar'usarmos 'foo'"'"'bar'.
2828 Scott
1

Eu tenho uma porta Windows de utilitários unix, então os comandos parecem um pouco diferentes, mas eu tinha um arquivo csv com vírgulas e aspas. Usando este tópico como guia, consegui remover as aspas por meio deste comando:

c:\Temp> cat report.csv | sed "s/\,/\ /g" | sed "s/[""]//g"
JaimeR744
fonte
obrigado! estava preso nisso!
sendbits 18/04