根据file命令将文件转换为utf-8

Pat*_*Pat 6 ksh

有一个上传过程,读取文件并使用 sqlldr 将数据上传到数据库。我在 sqlldr 中处理文件时遇到无效号码问题。发现文件是UTF-16格式,然后在notepad++中转换为UTF-8格式,它开始正常工作。现在我正在尝试系统地转换它,如下所示。

iconv -f UTF-16 -t UTF-8 file_name >output_file_name
Run Code Online (Sandbox Code Playgroud)

该文件可能具有不同的编码,因此我想在转换之前找到该文件的编码,然后根据该编码进行转换。例如使用 file 命令仅从下面读取 UTF-16,然后在 -f 选项中使用它。

bash-4.2$ file "/FILE_UPLOADS/Relationship (4).txt"
/FILE_UPLOADS/Relationship (4).txt: Little-endian UTF-16 Unicode text, with CRLF line terminators
Run Code Online (Sandbox Code Playgroud)

我怎么做?

Sté*_*las 7

vim能够自动检测一些文件编码并转换为 UTF-8,因此您可以尝试使用以下ex模式处理文件:

vim --clean -E -s -c 'argdo set fileencoding=utf-8 nobomb | update' -c q -- *.txt
Run Code Online (Sandbox Code Playgroud)

我们update也只重写在此过程中修改过的文件。


Sté*_*las 1

fileLittle-endian UTF-16 Unicode 文本或使用--mime-encoding utf-16le时,这意味着该文件以 UTF-16 编码,并带有指示它采用小尾数法的 BOM。

file无法检测没有 BOM 的 UTF-16 文本文件(小端或大端)。

对于 UTF-16 文本,它需要前两个字节为 0xff、0xfe(小端)或 0xfe 0xff(大端),然后检查前 64KiB 数据的其余部分是否看起来像文本(仅查找 UTF -16 编码的 ASCII 控制字符(文本文件中不需要)。

对于iconv,表示不带utf-16leBOM的小端 UTF-16 ,而 utf-16 表示带 BOM 的 utf-16,无论是大端还是小端。

因此,如果您使用 的输出file -b --mime-encoding作为中的from字符集iconv,您最终会在输出中得到 UTF-8 编码的 BOM。

在这里,您可能想要类似的东西:

encoding=$(file -b --mime-encoding - < "$file") &&
  case $encoding in
    (utf-16[bl]e) iconv -f UTF-16 < "$file" -t UTF-8 > "$newfile";;
    (us-ascii | utf-8) ;; # already utf-8
    (*) printf >&2 '%s\n' "don't know what to do with a $encoding encoding"
  esac
Run Code Online (Sandbox Code Playgroud)

如果这些是 Microsoft 文件(如 CRLF 所示),您可能需要dos2unix使用iconv. dos2unix(至少当前版本)应该能够检测 UTF-16 并转换为语言环境的字符集(LC_ALL=C.UTF-8 dos2unix如果您希望输出为 UTF-8,无论语言环境如何,请运行它)并将 CRLF 更改为 LF 并修复其他怪癖在微软的文件中。