将非 UTF-8 和 UTF-8-with-BOM 文件批量转换为 UTF-8

Bak*_*ap4 3 bash text utf-8 character-encoding

嘿,我正在尝试在 Ubuntu 上使用 bash 中的命令创建新文件find

我可以轻松列出文件并知道如何从中创建新文件,但我不希望编码随之而来。

现在我正在使用这个命令:find ./Polish\ 2\ \(copy\)/ -name '*.txt' -type f -exec sh -c 'cat <"$0" >"$0.txt"' {} \; 但是,如果文件不是 UTF-8 格式,我仍然想写入新文件$0.txtUTF-8 格式写入新文件。

自从我手动执行此操作以来,我就想到了这个想法:

  1. 我在 gedit 中打开非UTF8 文件。
  2. 复制内容。
  3. 创建一个新的空白文件。
  4. 用 gedit 打开它。
  5. 将复制的内容粘贴到文件中并保存

在我的例子中,gedit 的默认行为是保存为 UTF8。然而,有超过 30.000 个文件需要执行此操作,我不想手动执行此操作。

有默认内置工具的解决方案吗?

编辑

该文件可以即时编辑,而不是像我在示例中那样创建单独的文件。

iconv如果文件已经格式化,那么尝试转换文件时会发生什么UTF-8

编辑2.0

我希望最后能得到所有文件BOM

mkl*_*nt0 6

没有明确的方法可以仅通过文件内容来识别文件的字符编码,因此您能做的最好的事情就是在转换为 UTF-8 时假设最可能的输入编码( ,如您所述),使用; 为了避免转换已经是UTF-8 编码的文件,您可以使用以下方法来检测它们:CP1252iconvfile

注意:为了简单起见,我将find的目标目录更改为.

find . -type f -name '*.txt' -exec bash -c '
  descr=$(file -b "$0")
  if [[ $descr != *UTF-8* ]]; then
    iconv -f CP1252 -t UTF-8 "$0" > "$0.$$" && mv "$0.$$" "$0"
  elif [[ $descr == *"with BOM"* ]]; then
    tail -c +4 "$0" > "$0.$$" && mv "$0.$$" "$0"
  fi
' {} \;
Run Code Online (Sandbox Code Playgroud)

注意:如果将此命令转换为单行语句,则需要其他 ;实例,即after :
语句descr=...iconv ...语句和tail ...语句。

笔记:

  • file-b选项不符合 POSIX 标准,并且该标准也没有规定在输出中提及文件的编码BOM 存在。
    但实际上,上述内容应该适用于 Linux 和 macOS/BSD 系统。

  • UTF-8“BOM”(Unicode 签名,主要在Windows上使用)的长度为 3 个字节,因此如果通过 在输入文件中检测到它-filetail -c +4 则会跳过它,输出“无 BOM”UTF-8 文件。