Como remover o caracter especial 'M-BM-' com sed

4

Eu tenho um arquivo que foi criado copiando o conteúdo do documento DOCX com o LibreOffice para o arquivo de texto. Eu modifiquei o arquivo com sed para remover espaços adicionais e outras coisas, mas notei espaço imune ao comando normal:

sed -r 's:some-text :some-text:g' -i file

Depois de usar cat -A file , descobri que isso é assim:

<p>M-BM- Lorem ipsum</p>

Como remover isso?

    
por Rafal 12.10.2013 / 19:46

5 respostas

1

Depois de tentar muitas coisas, finalmente encontrei a solução. Para substituir esse caractere estranho por sed, você precisa copiar e colar o texto exato que contém esse espaço estranho perto dele e, em seguida, colá-lo diretamente no comando sed:

sed -r 's:paste-here:<p>:g' -i file

Qual será o seguinte no comando sed:

sed -r 's:<p> :<p>:g' -i file

mas funcionará mesmo assim.

    
por Rafal 12.10.2013 / 19:46
9

Os caracteres M-BM- são uma representação ASCII da sequência de bytes 0xc2 0xa0 , que é a codificação UTF8 do caractere unicode A0 - um caractere de espaço sem quebra. Este caractere pode ser inserido nos documentos do LibreOffice e do Microsoft Word usando a seqüência de teclas Ctrl + Deslocamento + ESPAÇO .

Por exemplo, se criarmos um novo documento .odt no LibreOffice e digitar ABC Ctrl + Deslocar + ESPAÇO DEF, então Save As... Text (ignorando o aviso de que o documento pode conter recursos que não podem ser salvos nesse formato), então visualize o arquivo .txt resultante com cat :

$ cat nbsp.txt 
ABC DEF

e novamente com a opção -v para mostrar caracteres não imprimíveis

$ cat -v nbsp.txt 
M-oM-;M-?ABCM-BM- DEF

Tenha em atenção que também obtemos uma sequência inicial M-oM-;M-? ou hexadecimal 0xef 0xbb 0xbf , que é a UTF8 marca de encomenda de bytes (BOM) consistente com o tipo de arquivo informado pelo comando file , por exemplo

$ file nbsp.txt 
nbsp.txt: UTF-8 Unicode (with BOM) text

Usando od para imprimir os valores hexadecimais em ordem de bytes,

$ od -tx1 nbsp.txt
0000000 ef bb bf 41 42 43 c2 a0 44 45 46 0a
0000014

É possível manipular esses caracteres usando ferramentas padrão como sed ou tr , especificando os códigos hexadecimais como sequências de escape, por exemplo. para substituir o espaço sem quebra por um espaço ASCII simples

$ sed 's/\xc2\xa0/ /g' nbsp.txt
ABC DEF

Verificar novamente com od confirma a substituição por um espaço ASCII comum 0x20 (decimal 32)

$ sed 's/\xc2\xa0/ /g' nbsp.txt | od -tx1
0000000 ef bb bf 41 42 43 20 44 45 46 0a
0000013

No gnome-terminal (e talvez outros emuladores de terminal compatíveis com UTF8), também é possível inserir o valor do ponto de código unicode diretamente usando a seqüência de teclas Ctrl + < kbd> Shift + u seguido por um valor hexadecimal e depois pela tecla Enter - a sequência aparece inicialmente como u̲.̲.̲.̲ mas depois o caractere deve compor quando você apertar Enter eg para a mesma substituição de espaço sem quebra que podemos fazer

$ sed 's/Ctrl+Shift+ua0

exibido como

$ sed 's/̲/̲u̲a̲0̲

e, em seguida, conclui como

$ sed 's/ / /g' nbsp.txt
ABC DEF

Usando cat -v , podemos confirmar que a sequência M-BM- se tornou um espaço comum

$ sed 's/ / /g' nbsp.txt | cat -v
M-oM-;M-?ABC DEF

Você pode querer ver conversores de codificação mais genéricos como iconv e uconv também.

    
por steeldriver 14.10.2013 / 02:08
1

Você pode remover ^ M dos arquivos diretamente por meio do comando sed, por exemplo:

sed -i'.bak' s/\r//g *.*

Se você estiver satisfeito com as alterações, remova os arquivos .bak:

rm -v *.bak
    
por kenorb 07.02.2014 / 17:06
0

"cat -v file" mostrará os caracteres não imprimíveis no arquivo. Apenas redirecione a saída para algum arquivo temporário e use o vim para substituir os caracteres M-BM por nada.

% s / M-BM- // g

Solução mais fácil.

    
por Prasad 16.04.2014 / 12:00
0

pequeno script para remover este demônio M-BM-caracter! ;) Apenas no caso será ajudar qualquer pessoa.

#!/bin/bash
#############################################################################
# SCRIPT:   M-BM-Remover.sh
# DESCRIPTION:
#           This script will be able to detect hidden caracter "M-BM-",
#               And/Or remove this !
# REVISIONS:
#           2014/06/11  YG
#____________________________________________________________________________
#
# PARAMETERS:
#  > $1  :TARGET,      (e.g. '"*.sh"' )
#  > $2  :ACTION,      (e.g. 'remove' )
#  > $2  :BACKUP,      (e.g. '' )
#
#############################################################################

TARGET=$1
ACTION=$2
BACKUP=$3

if [ "$TARGET" = "" ]
then
    echo 'Need to choose target file'
    echo 'M-BM-Remover [TARGET] [show/remove] [backup]'
    echo 'Example : M-BM-Remover "*.sh" remove backup'
    exit
fi

echo "ACTION = $ACTION";
echo "TARGET = $TARGET";
echo

if [ "$ACTION" = "show" ]
then
    for file in $TARGET
    do
        if [ "$file" != "M-BM-Remover.sh" ]
        then
            echo "Traitement de $file ..."
            cat -v $file | grep M-BM-
            NB='cat -v $file | grep M-BM- | wc -l'
            echo "Occurence(s) : $NB"
        fi
    done 
fi

if [ "$ACTION" = "remove" ] || [ "$ACTION" = "" ]
then
    for file in $TARGET
    do
        if [ "$file" != "M-BM-Remover.sh" ]
        then
            echo "Traitement de $file ..."
            NB='cat -v $file | grep M-BM- | wc -l'
            if [ "$BACKUP" = "backup" ]
            then
                cat $file > $file.bak
            fi
            cat -v $file.bak | sed s/M-BM-//g > $file
            echo "Occurence(s) removed : $NB"
        fi
        echo
    done 
fi
    
por YoannG 11.06.2014 / 16:13