我有一个使用 LibreOffice 将 DOCX 文档内容复制到文本文件而创建的文件。我修改了文件以sed
删除多余的空格和其他内容,但随后我注意到空格不受常规命令的影响:
sed -r 's:some-text :some-text:g' -i file
使用后cat -A file
我发现它看起来像这样:
<p>M-BM- Lorem ipsum</p>
如何删除它?
答案1
这些M-BM-
字符是字节序列的 ASCII 表示,它是 unicode 字符(不间断空格字符)0xc2 0xa0
的 UTF8 编码。可以使用键序列+ +将此字符插入 LibreOffice 和 Microsoft Word 文档中。A0
CtrlShiftSPACE
例如,如果我们在 LibreOffice 中创建一个新的 .odt 文档并输入 ABC Ctrl++ DEF,那么(忽略文档可能包含无法以该格式保存的功能的警告),然后使用以下命令查看生成的 .txtShift文件:SPACESave As... Text
cat
$ cat nbsp.txt
ABC DEF
然后再次切换-v
显示非打印字符
$ cat -v nbsp.txt
M-oM-;M-?ABCM-BM- DEF
请注意,我们还得到了一个初始序列M-oM-;M-?
或十六进制0xef 0xbb 0xbf
,即 UTF8字节顺序标记 (BOM)与命令报告的文件类型一致,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
通过将十六进制代码指定为转义序列来操作这些字符,例如用纯 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
在 gnome-terminal(也许还有其他支持 UTF8 的终端仿真器)中,也可以输入 unicode代码点值直接使用键序列Ctrl++ Shift,u后跟十六进制值,然后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
您可能需要查看更通用的编码转换器,例如图标和uconv也一样。
答案2
“cat -v file ”将显示文件中的非打印字符。只需将输出重定向到某个临时文件,然后使用 vim 将 M-BM- 字符替换为空即可。
%s/M-BM- //g
最简单的解决方案。
答案3
尝试了很多方法后,我终于找到了解决方案。要用 sed 替换那个奇怪的字符,您需要复制并粘贴包含奇怪空格的确切文本,然后将其直接粘贴到 sed 命令中:
sed -r 's:paste-here:<p>:g' -i file
在 sed 命令中看起来像这样:
sed -r 's:<p> :<p>:g' -i file
但无论如何它都会起作用。
答案4
您还可以将特殊的 unicode 字符粘贴到 sed 命令中,如下所示:
sed 's/ / /g'