如何递归转换 mime 编码(us-ascii 到 utf-8)

如何递归转换 mime 编码(us-ascii 到 utf-8)

us-ascii我的编码文件很少。我想将它们转换为utf-8递归。

要查找文件,我正在使用命令

find . -name "*.adoc" -type f -exec file --mime-encoding {} \; | grep -v ": us-ascii"

输出看起来像

./sds.adoc: us-ascii
./docker/misc/terms.adoc: us-ascii
./docker/misc/tools.adoc: us-ascii
./docker/basics-containers.adoc: us-ascii
./web-scraping/links.adoc: us-ascii
./system-design/reference-architecture.adoc: us-ascii
./system-design/replication vs load balancing.adoc: us-ascii
./system-design/performance.adoc: us-ascii
./system-design/links.adoc: us-ascii
./system-design/disaster-recovery.adoc: us-ascii

我想,要转换,我必须使用iconv -f us-ascii file.adoc -t UTF-8 -o file.adoc

我不明白该怎么做。

答案1

US-ASCII 是 UTF-8 的子集。 US-ASCII 仅涵盖字符 U+0000 到 U+007F,这些字符的编码在 US-ASCII 中与在 UTF-8 中相同(字节值对应于 Unicode 代码点(U 的字节值对应于 0x41 字节) +0041 字符 ( A) 例如))。

所以你没什么可做的。您的文件已经是 UTF-8 格式了。

file报告 us-ascii,因为从它查看的小子集来看,它看起来像文本,它没有高于 0x7f 的字节值,并且可能 1 使用的字符分布表明它比其他 7 位字符集(如 EBCDIC)更可能是 ASCII。

在这些上运行iconv -f us-ascii -t UTF-8会适得其反,因为最好的情况下它什么也不做,最坏的情况下你会丢失数据,因为如果file出错并且有高于 0x7f 的字节值(对于以 UTF-8 或其他字符集编码的高于 U+007F 的字符)它没有查看的部分iconv将因错误而中止,留下不完整的文件。


1 作为猜测,您需要查看 libmagic 代码以了解它使用什么启发式来猜测文本文件字符集,这通常是无法可靠确定的。

答案2

尝试这样的事情:

find . -name '*.adoc' -type f -execdir sh -c '
  for f; do
    file --mime-encoding "$f" | grep -qi us-ascii &&
      bn="$(basename "$f" .adoc)" && 
      iconv -f us-ascii "$f" -t UTF-8 -o "$bn-utf8.adoc"
  done' sh {} +

这将cd进入每个包含.adoc文件的目录,并且(对于该目录中的每个 .adoc 文件)如果file指示该文件是 us-ascii,则使用iconv它将其转换为 utf-8(使用不同的输出文件名)。

注意:该-execdir选项是非标准的,需要 GNU 或 BSD 版本的find. GNU 是 Linux 上的标准。


如果要将原始 us-ascii 文件替换为 utf-8 版本,请添加&&到该行末尾iconv并紧随其后添加以下行:

  mv "$bn-utf8.adoc" "$f"

相关内容