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

时间:2017-05-16 21:13:27

标签: bash text utf-8 character-encoding

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

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

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

每当我手动执行此操作时,我就会想到这个想法:

  1. 我在gedit中打开nonUTF8文件。
  2. 复制内容。
  3. 创建一个新的空白文件。
  4. 用gedit打开它。
  5. 将复制的内容粘贴到文件中并保存
  6. 在我的情况下,gedit的默认行为是保存为UTF8。但是有超过30.000个文件来执行此操作我不想手动执行此操作..

    使用默认内置工具的任何解决方案?

    修改

    该文件可以动态编辑,而不是像我在我的例子中那样创建一个单独的文件。

    如果文件已经采用iconv格式,尝试使用UTF-8转换文件时会发生什么?

    EDIT 2.0

    我希望在没有BOM

    的情况下最终拥有所有文件

1 个答案:

答案 0 :(得分:2)

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

注意:为简单起见,我已将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
' {} \;

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

注意:

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

  • UTF-8“BOM”(Unicode签名,主要用于 Windows )长度为3个字节,因此如果在输入文件中通过-b检测到它,-file 跳过,输出“无BOM”UTF-8文件。