Как удалить специальный символ 'M-BM-' с помощью sed

У меня есть файл, который был создан путем копирования содержимого из документа DOCX с помощью LibreOffice в текстовый файл. Я изменил файл с sed, чтобы удалить дополнительные пробелы и другие вещи, но затем я заметил пространство, которое было неуязвимо для обычной команды:

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

После использования cat -A file я обнаружил, что это выглядит так:

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

Как это убрать?

6
задан 24 July 2015 в 15:22

5 ответов

Попробовав много вещей, я наконец нашел решение. Чтобы заменить этот странный символ на sed, вам нужно скопировать и вставить точный текст, который содержит это странное пространство рядом с ним, а затем вставить его непосредственно в команду sed:

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

Выглядите так в команде sed:

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

, но все равно будет работать.

0
ответ дан 24 July 2015 в 15:22

M-BM- символы являются представлением ASCII последовательности байта 0xc2 0xa0, который является кодированием UTF8 unicode символа A0 - неразрывный пробел. Этот символ может быть вставлен и в LibreOffice и в документы Microsoft Word с помощью сочетания клавиш Ctrl+Shift+SPACE.

Например, если мы создаем новый .odt документ в LibreOffice и вводим ABCCtrl+Shift+SPACEDEF, затем Save As... Text (игнорирование предупреждения, что документ может содержать функции, которые не могут быть сохранены в том формате), затем просмотрите получающийся .txt файл с cat:

$ cat nbsp.txt 
ABC DEF

и с другой стороны с -v переключитесь для показа непечатаемых символов

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

Обратите внимание, что мы также получаем начальную последовательность M-oM-;M-? или шестнадцатеричный 0xef 0xbb 0xbf который является меткой порядка байтов (BOM) UTF8, согласовывающейся с типом файла, о котором сообщают file команда т.е.

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

Используя od для печати шестнадцатеричных значений в порядке байтов, мы видим

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

Возможно управлять этими символами с помощью стандартных инструментов как sed или tr путем определения шестнадцатеричного числа кодирует как escape-последовательности, например, заменять неразрывное пространство плоскостью пространство ASCII

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

Проверка снова с od подтверждает, что замена обычным ASCII располагает 0x20 с интервалами (десятичные 32)

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

В терминале гнома (и возможно другие UTF8-осведомленные эмуляторы терминала), также возможно ввести unicode значение кодовой точки непосредственно с помощью сочетания клавиш Ctrl+Shift+u, сопровождаемый шестнадцатеричным значением затем клавиша Enter - последовательность обнаруживается первоначально как u ̲. ̲. ̲. ̲, но затем символ должен сочинить, когда Вы совершаете нападки, Входят, например, для той же неразрывной замены пространства мы можем сделать

$ sed 's/Ctrl+Shift+ua0

который отображается как

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

и затем завершается как

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

Используя cat -v мы можем подтвердить M-BM- последовательность стала обычным пространством

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

Можно хотеть посмотреть на большее количество универсальных преобразователей кодирования, таких как iconv и uconv также.

11
ответ дан 24 July 2015 в 15:22

Вы можете удалить ^ M из файлов напрямую с помощью команды sed, например, :

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

Если изменения вас устраивают, удалите файлы .bak:

rm -v *.bak
0
ответ дан 24 July 2015 в 15:22

«cat -v file» покажет непечатаемые символы в файле. Просто перенаправьте вывод во временный файл и используйте vim для замены символов M-BM ничем.

% s / M-BM- // g

Самое простое решение.

0
ответ дан 24 July 2015 в 15:22

Небольшой скрипт для удаления этого дьявола M-BM-персонажа! ;) На всякий случай помогут любые люди.

#!/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
ответ дан 24 July 2015 в 15:22

Другие вопросы по тегам:

Похожие вопросы: