web-dev-qa-db-fra.com

Comment supprimer le caractère spécial 'M-BM-' avec sed

J'ai un fichier créé en copiant le contenu d'un document DOCX avec LibreOffice dans un fichier texte. J'ai modifié le fichier avec sed pour supprimer des espaces supplémentaires et d'autres éléments, mais j'ai remarqué un espace insensible aux commandes habituelles:

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

Après avoir utilisé cat -A file, j'ai découvert que cela ressemblait à ceci:

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

Comment l'enlever?

6
Rafal

Après avoir essayé beaucoup de choses, j'ai finalement trouvé une solution. Pour remplacer ce caractère étrange par sed, vous devez copier et coller le texte exact qui contient cet espace étrange à proximité, puis le coller directement dans la commande sed:

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

Ce qui ressemblera à ceci dans la commande sed:

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

mais cela fonctionnera quand même.

1
Rafal

Les caractères M-BM- sont une représentation ASCII de la séquence d'octets 0xc2 0xa0, qui est le codage UTF8 du caractère unicode A0 - un espace insécable. Ce caractère peut être inséré dans les documents LibreOffice et Microsoft Word en utilisant la séquence de touches Ctrl+Shift+SPACE.

Par exemple, si nous créons un nouveau document .odt dans LibreOffice et tapons ABCCtrl+Shift+SPACEDEF, puis Save As... Text (sans tenir compte du fait que le document peut contenir des fonctions qui ne peuvent pas être enregistrées dans ce format), puis affichez le fichier .txt obtenu avec cat:

$ cat nbsp.txt 
ABC DEF

et ensuite avec le commutateur -v pour afficher les caractères non imprimables

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

Notez que nous obtenons également une séquence initiale M-oM-;M-? ou hexadécimale 0xef 0xbb 0xbf qui correspond à UTF8 marque d'ordre des octets (BOM) cohérente avec le type de fichier indiqué par file commande c'est à dire.

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

Utiliser od pour imprimer les valeurs hexadécimales dans l'ordre des octets que nous voyons

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

Il est possible de manipuler ces caractères à l'aide d'outils standard tels que sed ou tr en spécifiant les codes hexadécimaux sous forme de séquences d'échappement, par ex. remplacer l'espace insécable par un espace ASCII

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

Vérifier à nouveau avec od confirme le remplacement par un ASCII espace 0x20 (décimal 32) ordinaire.

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

Dans gnome-terminal (et peut-être avec d'autres émulateurs de terminal compatibles UTF8), il est également possible de saisir la valeur du point de code unicode directement à l'aide de la séquence de touches. Ctrl+Shift+u suivi d'une valeur hexadécimale puis le Enter key - la séquence apparaît initialement sous la forme u..̲. mais le personnage doit composer lorsque vous appuyez sur Enter par exemple. pour le même remplacement d'espace insécable que nous pouvons faire

$ sed 's/Ctrl+Shift+ua0

qui affiche comme

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

puis complète comme

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

En utilisant cat -v nous pouvons confirmer que la séquence M-BM- est devenue un espace ordinaire

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

Vous voudrez peut-être examiner des convertisseurs de codage plus génériques tels que iconv et uconv ainsi que.

11
steeldriver

"cat -v file" montrera les caractères non imprimables du fichier. Il suffit de rediriger la sortie vers un fichier temporaire et d’utiliser vim pour remplacer les caractères M-BM par rien.

% s/M-BM- // g

La solution la plus simple.

1
Prasad

Vous pouvez supprimer ^ M des fichiers directement via la commande sed, par exemple:

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

Si les modifications vous conviennent, supprimez les fichiers .bak:

rm -v *.bak
1
kenorb

petit script pour supprimer ce caractère diable M-BM! ;) Juste au cas où aiderait n'importe qui.

#!/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
0
YoannG