Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何最好地将混合编码的邮箱文件转换为UTF-8?_Linux_Bash_Shell_Email_Character Encoding - Fatal编程技术网

Linux 如何最好地将混合编码的邮箱文件转换为UTF-8?

Linux 如何最好地将混合编码的邮箱文件转换为UTF-8?,linux,bash,shell,email,character-encoding,Linux,Bash,Shell,Email,Character Encoding,我有一个.mbox邮箱文件,其中包含数千封不同语言的电子邮件,分别以ASCII、ISO-8859-1和UTF-8编码。我想将文件“展平”为UTF-8 我的第一个工作是循环遍历文件,对每个字符执行file-b--mime编码,对任何检测到的ISO-8859-1字符执行iconv-f ISO-8859-1-t UTF-8。我知道UTF-8是ASCII的超集,所以只有ISO-8859-1需要转换 这花了很长时间,但由于某些原因并没有像预期的那样起作用。问题人物依然存在 有没有一种明显的方法可以做到这一

我有一个.mbox邮箱文件,其中包含数千封不同语言的电子邮件,分别以ASCII、ISO-8859-1和UTF-8编码。我想将文件“展平”为UTF-8

我的第一个工作是循环遍历文件,对每个字符执行
file-b--mime编码
,对任何检测到的ISO-8859-1字符执行
iconv-f ISO-8859-1-t UTF-8
。我知道UTF-8是ASCII的超集,所以只有ISO-8859-1需要转换

这花了很长时间,但由于某些原因并没有像预期的那样起作用。问题人物依然存在


有没有一种明显的方法可以做到这一点,或者是否有必要借助
formail
将文件消息转换为消息?

据我所知,MIME邮件及其容器。mbox文件始终以ASCII格式编码,非ASCII源字符以QP格式显示

  • 例如,“é”在所有my.mbox文件中都用“=E9”表示(无论消息的原始编码是什么)
  • 参见编码
这意味着,您将遇到的任何原始非ascii字符都不会出现在iso-8859-1或其他版本中,而是已经被转换成符合以下正则表达式的内容:
=[0-9A-F]{2}

通过这种方式,您可以简单地使用
sed
echo-e
转换QP编码

sed -re 's/=([0-9A-F]{2})/\\\\u00\1/g' | while read L ; do echo -e $L ; done
说明:

  • sed将把两个十六进制数字(如“=E9”)的所有QP形式替换为unicode代码点(如“\u00E9”)
  • echo-e可以将后者转换为字符形式(从Bash4.2开始)

据我所知,MIME邮件及其容器。mbox文件始终以ASCII格式编码,非ASCII源字符以QP格式显示

  • 例如,“é”在所有my.mbox文件中都用“=E9”表示(无论消息的原始编码是什么)
  • 参见编码
这意味着,您将遇到的任何原始非ascii字符都不会出现在iso-8859-1或其他版本中,而是已经被转换成符合以下正则表达式的内容:
=[0-9A-F]{2}

通过这种方式,您可以简单地使用
sed
echo-e
转换QP编码

sed -re 's/=([0-9A-F]{2})/\\\\u00\1/g' | while read L ; do echo -e $L ; done
说明:

  • sed将把两个十六进制数字(如“=E9”)的所有QP形式替换为unicode代码点(如“\u00E9”)
  • echo-e可以将后者转换为字符形式(从Bash4.2开始)

recode
支持从表面解码,即
引用可打印的
Base64
以及字符集。所以你会这样做:

recode CP1252/QP..UTF-8 < filein > fileout
重新编码CP1252/QP..UTF-8
filein>fileout
现在有一个“真正”的问题(我的重点):

数千封不同语言的电子邮件,以ASCII、ISO-8859-1和UTF-8进行不同编码

这些文件之间的重新编码请求不同。简单地说,ASCII和UTF-8文件不需要重新编码。您需要检查所有这些文件并找出iso-8859-1文件:

find . -name "*.mbox" -exec file -i "{}" ";" \
   | grep -v "\(us-ascii\|utf-8\)$" \
   | sed -e 's/^\([^:]*\): .*; charset=\([^=]*\)$/recode \2\/QP..utf-8 < "\1" > "\1.tmp" && mv "\1.tmp" "\1"/g' \
   > recode-script.sh
find-名称“*.mbox”-exec文件-i“{}”;“\
|grep-v“\(美国ascii\\ utf-8\)$”\
|sed-e的/^\([^::*\):*;字符集=\([^=]*\)$/recode\2\/QP..utf-8<“\1”>“\1.tmp”和&mv“\1.tmp”\1”/g”\
>recode-script.sh
另一个问题是,至少在我有限的经验中,很大部分文件可能没有编码在引用的可打印表面中(你会注意到,
文件
识别ISO-8859-1,即使引用的可打印文件实际上给了你一个ASCI7文件),你需要识别它们,这需要解析mbox格式(另一个原因是,虽然不太可能,但在同一消息中甚至可能有具有不同字符集和/或表面的不同多部分节,并且使用单个矩阵直接解码整个文件会解码某些节并损坏其他节)

因此,为了获得最佳效果,除非您确定您只有ISO-8859-1(5)文件,
formail
是您的朋友。您可以使用上述脚本的变体对文件进行预筛选,以关注实际需要转换的文件(生成为ascii或utf-8的文件无需修改)。如果您发现需要重新编码的文件都在同一个曲面中,则
recode
可能具有最佳性能


注意:我记得看到一个实用程序,它可以在输入中获取文本文件的列表,并在一个流中输出这些文件,其中“>>
recode
支持从表面解码,即
引用可打印的
Base64
以及字符集。因此,您可以:

recode CP1252/QP..UTF-8 < filein > fileout
重新编码CP1252/QP..UTF-8
filein>fileout
现在有一个“真正”的问题(我的重点):

数千封不同语言的电子邮件,以ASCII、ISO-8859-1和UTF-8进行不同编码

这些文件之间的重新编码请求不同。一般来说,ASCII和UTF-8文件不需要重新编码。您需要检查所有这些文件并找出iso-8859-1文件:

find . -name "*.mbox" -exec file -i "{}" ";" \
   | grep -v "\(us-ascii\|utf-8\)$" \
   | sed -e 's/^\([^:]*\): .*; charset=\([^=]*\)$/recode \2\/QP..utf-8 < "\1" > "\1.tmp" && mv "\1.tmp" "\1"/g' \
   > recode-script.sh
find.-name“*.mbox”-exec文件-i“{}”;“\
|grep-v“\(美国ascii\\ utf-8\)$”\
|sed-e的/^\([^:]*\):.*;字符集=\([^=]*\)$/recode\2\/QP..utf-8<“\1”>“\1.tmp”和&mv“\1.tmp”“\1”/g”\
>recode-script.sh
另一个问题是,至少在我有限的经验中,很大部分文件可能没有编码在引用的可打印表面中(你会注意到,
文件
识别ISO-8859-1,即使引用的可打印文件实际上给了你一个ASCI7文件),你需要识别它们,这需要解析mbox格式(另一个原因是,虽然不太可能,但您甚至可以在同一消息中具有不同字符集和/或曲面的不同多部分节,