LibreOfficeを使用してDOCXドキュメントのコンテンツをテキストファイルにコピーして作成したファイルがあります。 sed
でファイルを変更して、追加のスペースやその他のものを削除しましたが、通常のコマンドの影響を受けないスペースに気付きました。
sed -r 's:some-text :some-text:g' -i file
cat -A file
を使用した後、次のようになっていることがわかりました。
<p>M-BM- Lorem ipsum</p>
削除する方法は?
多くのことを試した後、私は最終的に解決策を見つけました。その奇妙な文字をsedに置き換えるには、その近くにその奇妙なスペースを含む正確なテキストをコピーして貼り付けてから、sedコマンドに直接貼り付ける必要があります。
sed -r 's:paste-here:<p>:g' -i file
Sedコマンドでは次のようになります。
sed -r 's:<p> :<p>:g' -i file
とにかく動作します。
M-BM-
文字は、バイトシーケンス0xc2 0xa0
のASCII表現です。これは、Unicode文字のUTF8エンコードA0
-改行しないスペース文字です。この文字は、キーシーケンスを使用してLibreOfficeとMicrosoft Wordドキュメントの両方に挿入できます Ctrl+Shift+SPACE。
たとえば、LibreOfficeで新しい.odtドキュメントを作成し、ABCと入力した場合Ctrl+Shift+SPACEDEF、次にSave As... Text
(ドキュメントにその形式では保存できない機能が含まれている可能性があるという警告を無視)、結果の.txtファイルをcat
で表示します。
$ cat nbsp.txt
ABC DEF
その後、-v
スイッチを使用して、非印刷文字を表示します
$ cat -v nbsp.txt
M-oM-;M-?ABCM-BM- DEF
また、file
コマンドによって報告されるファイルタイプと一致するUTF8 バイトオーダーマーク(BOM) である初期シーケンスM-oM-;M-?
または16進数0xef 0xbb 0xbf
を取得することに注意してください。
$ file nbsp.txt
nbsp.txt: UTF-8 Unicode (with BOM) text
od
を使用して、16進値をバイト順で出力します
$ od -tx1 nbsp.txt
0000000 ef bb bf 41 42 43 c2 a0 44 45 46 0a
0000014
エスケープシーケンスとして16進コードを指定することにより、sed
やtr
などの標準ツールを使用してこれらの文字を操作することができます。非分割スペースをプレーンASCIIスペースに置き換える
$ sed 's/\xc2\xa0/ /g' nbsp.txt
ABC DEF
od
で再度確認すると、通常のASCIIスペース0x20(10進数32)による置換が確認されます。
$ sed 's/\xc2\xa0/ /g' nbsp.txt | od -tx1
0000000 ef bb bf 41 42 43 20 44 45 46 0a
0000013
Gnome-terminal(および他のUTF8対応ターミナルエミュレータ)では、キーシーケンスを使用してunicodecode point valueを直接入力することもできます Ctrl+Shift+u その後に16進数値が続き、 Enter キー-シーケンスは最初はu̲.̲.̲.̲として表示されますが、ヒットするとキャラクターが構成されます Enter 例えば私たちができる同じノンブレークスペースの交換のために
$ 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などのより一般的なエンコーディングコンバーターもご覧ください。
「cat -v file」は、ファイル内の非印刷文字を表示します。出力を一時ファイルにリダイレクトし、Vimを使用してM-BM-文字を何も置き換えないでください。
%s/M-BM- // g
最も簡単なソリューション。
Sedコマンドを使用して、ファイルから^ Mを直接削除できます。例:
sed -i'.bak' s/\r//g *.*
変更に満足したら、.bakファイルを削除します。
rm -v *.bak
この悪魔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