linux - 如何以自动方式搜索、替换特定的十六进制代码

标签 linux bash

我有一个 100M 行的文件,它有一些编码问题——“最初”是 EBCDIC,保存为 US-ASCII,现在是 UTF-8。我对它的传承知之甚少,抱歉——我刚刚被要求分析内容。

来自 EBCDIC 的“cents”字符“隐藏”在这个文件的随机位置,导致各种错误。这是关于这个错误的更多信息:cents character in hex

使用 iconv -f foo -t UTF-8 -c 转换此文件无效——美分字符占优势。

当我使用十六进制编辑器时,我可以找到0xC2 0xA2 (c2a2) 的外观。但在大文件中,这并不理想。 Sed 不能在十六进制级别工作,所以...不确定 tr——我只真正将它用于回车/换行。

我可以使用什么 linux 实用程序/命令在非常大的文件上合理快速地查找和删除此字符?

2 部分:

 1 -- utility / command to find / count the number of these occurrences (octal \242)
 2 -- command to replace (this works  tr '\242' ' ' < source > output )

文本在我的 ubuntu 终端上的显示方式:

1019EQ?IT DEPT GENERATED 

对于 xxd,它在十六进制级别的外观(旁边的 ascii 看起来与上面相同):

0000000: 3130 3139 4551 a249 5420 4445 5054 2047 454e 4552 4154 4544 0d0a 

对于 xxd,“show ebcdic”看起来如何——在这里,只是从侧面显示 ebcdic:

......s.....&....+........

所以十六进制“a2”是罪魁祸首。我现在正在尝试 xxd -E foo | grep a2 来计算实例。

为那些感兴趣的人添加 od -ctxl 的输出,而不是 xxd 的输出:

 0000000   1   0   1   9   E   Q 242   I   T       D   E   P   T       G
          31  30  31  39  45  51  a2  49  54  20  44  45  50  54  20  47
 0000020   E   N   E   R   A   T   E   D  \r  \n
          45  4e  45  52  41  54  45  44  0d  0a

最佳答案

当你说文件被转换时,你是什么意思?您是说二进制文件只是从 IBM 360 转储到另一台基于 ASCII 的计算机,还是在传输时文件本身已转换为 ASCII?

问题是文件是否实际上处于编码良好的状态。另一个问题是您希望文件如何编码?

在我的 Mac 上(默认使用 UTF-8,就像 Linux 系统一样),我可以使用 sed 去除 ¢ 字符:

这是我的文件:

$ cat test.txt
This is a test --¢-- TEST TEST
$ od -ctx1 test.txt
0000000    T   h   i   s       i   s       a       t   e   s   t       -
           54  68  69  73  20  69  73  20  61  20  74  65  73  74  20  2d
0000020    -   ¢  **   -   -       T   E   S   T       T   E   S   T  \n
           2d  c2  a2  2d  2d  20  54  45  53  54  20  54  45  53  54  0a
0000040

您可以看到 cat 打印出 ¢ 字符没有问题。并且,您可以在 od 转储中看到 ¢ 字符的 c2a2 编码。

$ sed 's/¢/$/g' test.txt > new_test.txt
$ cat new_test.txt
This is a test --$-- TEST TEST
$ od -ctx1  new_test.txt
0000000    T   h   i   s       i   s       a       t   e   s   t       -
           54  68  69  73  20  69  73  20  61  20  74  65  73  74  20  2d
0000020    -   $   -   -       T   E   S   T       T   E   S   T  \n    
           2d  24  2d  2d  20  54  45  53  54  20  54  45  53  54  0a    
0000037

这是我的 sed 将 ¢ 更改为 $ 符号没有问题。转储现在显示此测试文件等同于严格的 ASCII 编码文件。这两个十六进制数字编码 ¢ 现在是一个漂亮干净的单个十六进制数字编码 $

看起来 sed 可以解决您的问题。

如果你想在Windows系统上使用这个文件,你可以把这个文件转换成标准的Windows代码页1252:

$ iconv -f utf8 -t cp1252 test.txt > new_test.txt 
$ cat new_test.txt 
This is a test --?-- TEST TEST
$ od -ctx1  new_test.txt
0000000    T   h   i   s       i   s       a       t   e   s   t       -
           54  68  69  73  20  69  73  20  61  20  74  65  73  74  20  2d
0000020    - 242   -   -       T   E   S   T       T   E   S   T  \n    
           2d  a2  2d  2d  20  54  45  53  54  20  54  45  53  54  0a    
0000037

这是代码页 1252 中的文件,就像 Windows 喜欢的方式一样!请注意,¢ 现在是一个漂亮的十六进制 242 字符。

那么,到底是什么问题呢?您是否需要以 纯 ASCII 定义 127 个字符的方式归档?您是否需要对文件进行编码,以便 Windows 机器可以处理它?您在输入 ¢ 字符时遇到问题吗?

告诉我。我不是政府人员,但我是来帮助你的。

关于linux - 如何以自动方式搜索、替换特定的十六进制代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17891766/

相关文章:

c - 将输出重定向到 linux 中的文件

linux - 卸载Redis CentOS 7

python - Pygame 或 Python 中的透明窗口

Linux 薄荷 : install subversion 1. 7

linux - getopt 不支持 Bash 中选项之间的空格?

linux - 将 Oracle DATE 转换为 Linux 时间

bash - 如何使用 bash 脚本在文件中输出第一行 curl 结果

python - 使用 Paramiko (Python) 通过 SSH 执行 smartctl 命令时没有输出

linux - Bash Linux 上的选择菜单错误

mysql - Bash 转义(MySQL GRANT ALL PRIVILEGES 失败)