我们有一个文本文件,我们想要清除“坏”字符。如果我们用 vim 打开它(使用“:set number”):
57000044 zo¥<9a>¥ge¥o¥graph¥i¥cal¥ly
39999999 pariá¹<83>Å<9b>a
例如:“<9a>”和“<83>”和“<9b>”在 vim 中标记为蓝色,这两行在 vim 之外看起来像这样:
$ sed '57000044,57000044!d' toclean.txt
zo���ge�o�graph�i�cal�ly
$ sed '57000044,57000044!d' toclean.txt | cat -vte -
zoM-%M-^ZM-%geM-%oM-%graphM-%iM-%calM-%ly$
$
和
$ sed '39999999,39999999!d' toclean.txt
pariṃśa
$ sed '39999999,39999999!d' toclean.txt | cat -vte -
pariM-aM-9M-^CM-EM-^[a$
$
问题:我们如何找出上述“<9a>”、“<83>”和“<9b>”的十六进制ASCII字符是什么?或“1”或“¥”...
需要十六进制代码才能将其从文件中全部删除以使其更干净。示例此代码删除十六进制 ASCII“x09”,因此“水平制表符”:
sed -i 's/[\x09]//g' toclean.txt
我们尝试使用十六进制的“9A”或“A5”,但没有帮助。
$ sed '57000044,57000044!d' toclean.txt | sed 's/[\x9A]//g; s/[\xA5]//g'
zo���ge�o�graph�i�cal�ly
zo���ge�o�graph�i�cal�ly
$
答案1
代码 hex:<9a> 和 hex:<83> 不是 ASCII 代码(ASCII 代码仅从 <00> 到 <7F>)。您也无法“找出”哪些字符(来自任何比 ASCII 更大的字符集)与这些代码关联,因为这取决于基础字符集(“代码页”)编码。因此,您必须询问创建该数据的人他使用了什么字符编码。 (您经常发现的典型编码是 ISO 8859-1、ISO 8859-15、UTF-8、UCS-2。您还可以检查在网上找到的代码表,哪些带有这些索引的字符在您的数据上下文中最有意义.)
一旦知道要删除的代码值,您就可以(例如)使用tr
带选项的命令-d
(八进制参数)。
答案2
ASCII码是一个7位字符集。值大于 128 的字符是非 ASCII 字符。
如果你使用统一码,请注意,一个字符由多个字节表示(只有 256 个不同的字节值,但 Unicode 字符却超过 100000 个)。 Unicode 事实上的标准表示是UTF-8每个字符使用可变的字节数; ASCII 字符由单个字节表示,其他字符由 2 到 4 个字节表示。
Vim 显示一些带有蓝色占位符的字符,例如<9a>
因为这些字节不属于当前指定的字符集中的有效字符表示形式语言环境。
如果您想处理字节,请将区域设置设置LC_CTYPE
为C
。
LC_CTYPE=C vim toclean.txt
如果您想使用 UTF-8,请在 Unicode 终端上运行 Vim。
您可以使用以下命令显示文件中的字节od
(POSIX)或hexdump
(BSD,常见于 Linux 上)。
od -t x1 toclean.txt
hexdump -C toclean.txt
hd toclean.txt
如果您确定要删除某些字节值,则可以使用tr
。
LC_CTYPE=C tr -d '\x83\xa5' toclean.txt >clean.txt
如果您确定要删除某些 UTF-8 字符,请tr
在具有 UTF-8 编码的区域设置中使用,例如
LC_CTYPE=en_US.utf8 tr -d '¥' toclean.txt >clean.txt
答案3
我能找到的从文本文件中删除“非 ASCII”字符的最简单的解决方案是这个线程。
$ tr -cd '\000-\777' <脏文件> 干净文件
'\000-\777' 定义八进制的 ascii 集。 “-c”是给定集的补充,又名“非 ASCII”,“-d”删除字符。
答案4
你可以只使用luit
.其目的是干净的终端文本以适应系统的编码,并充当不正确处理 unicode 和终端的应用程序之间的透明过滤器 - 或反之亦然。
您几乎肯定已经安装了它 - 它是标准配置,X
因为xterm
如果它检测到主机上的编码问题,就会自动调用它。
它的man
页面描述了这个与 交互的示例Emacs
:
luit
对于硬连线编码与系统上通常使用的编码不同或想要使用旧转义序列进行多语言输出的应用程序也很有用。特别是,Emacs
不能很好地使用 UTF-8 的版本可以用于luit
多语言输出:$ luit -encoding 'ISO 8859-1' emacs -nw
然后,在
Emacs
,M-x set-terminal-coding-system RET iso-2022-8bit-ss2 RET
不过,除了直接终端应用程序之外,它还支持...
-c Function as a simple converter from standard
input to standard output.
所以可能会这样使用...
luit -c <infile >outfile