Substituindo pontos (.) No sed

9

Então, a pergunta real é: alguém tem uma idéia de como remover M-BM-caracteres especiais sem correr o risco de perder outros caracteres?

Eu tenho uma sequência de texto:

" . . ."

isso é

space dot space dot space dot

Estou tentando substituir toda a ocorrência dessa seqüência no arquivo de texto para

"..."

isso é

dot dot dot

Eu estava tentando fazer com sed:

sed -r 's:\s\.\s\.\s\.:...:g' -i sed-dots

Infelizmente, ele não altera nem um pouco o arquivo de entrada. Arquivo: https://www.dropbox.com/s/46zmiruy3ln85a1/sed-dots

Quando tento substituir a mesma string no editor de texto (eu uso o geany), ela é encontrada e substituída corretamente.

A única razão pela qual consigo pensar é que alguns (ou todos) desses espaços não são realmente espaços, mas algum caráter especial.

Alguém tem idéia de como encontrar e substituir essa string por sed (ou qualquer outra ferramenta de linha de comando)? Teste sua idéia no meu arquivo, pois o problema não é tão óbvio quanto parece - por isso perguntei.

Depois de usar o cat -Amyfile, parece problema que esses espaços não sejam espaços, mas M-BM-caracteres especiais. Usar qualquer símbolo .sugerido para pesquisa não é uma boa ideia, pois existe o risco de outros caracteres serem removidos.

Rafal
fonte

Respostas:

9

Primeiro eu começaria testando echoe canalizando isso para sed, do que usando um arquivo real. Em segundo lugar, você pode usar a {n}no modelo de expressão regular estendida para indicar múltiplos e limites.

Você estava praticamente lá, mas seu regex esperava um espaço de liderança.

$ echo 'cheese . . . muffins' | sed -r 's/(\s?\.){3}/ dot dot dot/g'
cheese dot dot dot muffins

Observe que \s?ainda é ganancioso o suficiente para arruinar a saída, então adicionei um espaço à saída. Você pode não querer isso. Também tornei o espaço opcional, para que ele corresponda a todos os seguintes itens:

...
. ..
.. .
. . .
 . . . 

Basta remover o ?sinalizador opcional .


Dado o seu problema com o unicode (nos comentários), você pode forçar os dados à sua equivalência ASCII iconve sedá-los:

$ iconv -f utf-8 -t ascii//translit sed-dots | sed -r 's/(\s?\.){3}/ dot dot dot/g'
Lorem ipsum dot dot dot
Some dot dot dot more text
Oli
fonte
Estou surpreso que você recomende usar em echovez de criar um arquivo, pelo menos quando você cria um arquivo, você sabe que o shell não está interpretando nada e nem é eco.
Flimm
@ Limite para um exemplo simples com pontos, isso não é realmente um problema. Se você deseja carregar de um arquivo, não se preocupe cat- basta sedcarregar o arquivo (conforme o exemplo do OP), mas não salvar em linha (remova -i, para que você possa ver e testar a saída).
Oli
@ Oli Funciona com o seu exemplo, mas não funciona com o meu arquivo (na minha pergunta, há um link). Isso é problema - seu comando e outros devem funcionar, mas não funcionam, pois há algum problema com esses pontos. Por favor, teste seu comando no meu arquivo e você verá que ele não funciona.
Rafal 21/03
11
@ Rafal Se você olhar, cat -A sed-dotspode ver que os "espaços" entre os pontos são M-BM- caracteres especiais ... Não sei como eles entraram lá, mas precisam ser substituídos. Se você não pode direcioná-los bem, isso funciona: sed -r 's/(\s\..\..\.)/ dot dot dot/ig' sed-dots
Oli
@Oli Funciona. Muito obrigado! Você poderia explicar a sintaxe? Tem certeza de que não tem efeitos colaterais e não substitui mais nada? Tanto quanto vejo, esse RegExp corresponderá a qualquer caractere após pontos. No entanto, M-BM não é um personagem, é três. Então, como isso pode funcionar?
Rafal 22/03
0

Tente o seguinte para substituir todos os "." Para "."

sed -r 's/\. /\./g' -i sed-dots

Mas pelo ". . ." para "..."

sed -r 's/\. \. \./\.\.\./g' -i sed-dots
Meer Borg
fonte
0

Eu poderia usar seu arquivo quando o executei:

tr '\240' ' ' < sed-dots.txt > sed-dots.new

Isso funcionou sem uma etapa de conversão:

sed 's/[[:blank:]]\.[[:blank:]]\.[[:blank:]]\./.../g' sed-dots.txt
Scrutinizer
fonte
Não funciona. Eu acho que esse motivo é um personagem M-BM estranho que a @Oli encontrou.
Rafal 22/03