如何通过脚本在Unix中找到文件的编码

时间:2009-04-30 05:13:48

标签: file shell unix encoding

我需要找到放在目录中的所有文件的编码。有没有办法找到使用的编码?

file命令无法执行此操作。

我感兴趣的编码是:ISO-8859-1。如果编码是其他任何东西,我想将文件移动到另一个目录。

17 个答案:

答案 0 :(得分:348)

听起来你正在寻找enca。它可以猜测甚至在编码之间进行转换。只需查看man page

或者,如果不这样做,请使用file -i(linux)或file -I(osx)。这将输出文件的MIME类型信息,其中还包括字符集编码。我也发现了man-page:)

答案 1 :(得分:67)

file -bi <file name>

如果您喜欢为一堆文件执行此操作

for f in `find | egrep -v Eliminate`; do echo "$f" ' -- ' `file -bi "$f"` ; done

答案 2 :(得分:27)

uchardet - 从Mozilla移植的编码检测器库。

用法:

~> uchardet file.java 
UTF-8

各种Linux发行版(Debian / Ubuntu,OpenSuse-packman,...)提供二进制文件。

答案 3 :(得分:9)

这是一个使用文件-I和iconv的示例脚本,它适用于MacOsX 对于您的问题,您需要使用mv而不是iconv

#!/bin/bash
# 2016-02-08
# check encoding and convert files
for f in *.java
do
  encoding=`file -I $f | cut -f 2 -d";" | cut -f 2 -d=`
  case $encoding in
    iso-8859-1)
    iconv -f iso8859-1 -t utf-8 $f > $f.utf8
    mv $f.utf8 $f
    ;;
  esac
done

答案 4 :(得分:5)

确定它是否是iso-8859-1真的很难。如果你的文本只有7位字符,也可能是iso-8859-1,但你不知道。如果您有8位字符,那么上面区域字符也存在于顺序编码中。因此,您必须使用字典来更好地猜测它是哪个单词,并从那里确定它必须是哪个字母。最后,如果你发现它可能是utf-8而不是你确定它不是iso-8859-1

编码是最困难的事情之一,因为你永远不知道是否有什么东西告诉你

答案 5 :(得分:2)

使用Python,您可以使用chardet模块:https://github.com/chardet/chardet

答案 6 :(得分:2)

要将编码从8859转换为ASCII:

iconv -f ISO_8859-1 -t ASCII filename.txt

答案 7 :(得分:2)

如果您正在谈论XML文件(ISO-8859-1),其中的XML声明指定了编码:<?xml version="1.0" encoding="ISO-8859-1" ?>
因此,您可以使用正则表达式(例如使用perl)来检查每个文件是否符合此类规范 可以在此处找到更多信息:How to Determine Text File Encoding

答案 8 :(得分:2)

在Debian中,您还可以使用:encguess

$ encguess test.txt
test.txt  US-ASCII

答案 9 :(得分:1)

这不是你能以万无一失的方式做的事情。一种可能性是检查文件中的每个字符,以确保它不包含范围0x00 - 0x1f0x7f -0x9f中的任何字符,但正如我所说,对于任意数量的文件都可能是这样的,包括ISO8859的至少一个其他变体。

另一种可能性是在所有支持的语言中查找文件中的特定单词,看看是否可以找到它们。

因此,例如,在所有支持的8859-1语言中找到相当于英语“and”,“but”,“to”,“of”等等,看看它们是否有大量的在文件中出现。

我不是在谈论字面翻译,例如:

English   French
-------   ------
of        de, du
and       et
the       le, la, les

虽然这是可能的。我正在谈论目标语言中的常用词语(据我所知,冰岛人没有“和”的说法 - 你可能不得不用他们的词来表示“鱼”[抱歉这有点陈旧,我没有意味着任何冒犯,只是说明一点])。

答案 10 :(得分:1)

我知道你对更一般的答案很感兴趣,但是ASCII的好处通常在其他编码中很好。这是一个Python单行程序,用于确定标准输入是否为ASCII。 (我很确定它适用于Python 2,但我只在Python 3上测试过它。)

python -c 'from sys import exit,stdin;exit()if 128>max(c for l in open(stdin.fileno(),"b") for c in l) else exit("Not ASCII")' < myfile.txt

答案 11 :(得分:0)

在Cygwin中,这看起来对我有用:

find -type f -name "<FILENAME_GLOB>" | while read <VAR>; do (file -i "$<VAR>"); done

示例:

find -type f -name "*.txt" | while read file; do (file -i "$file"); done

您可以将其传输到awk并创建一个iconv命令,将所有内容从iconv支持的任何源编码转换为utf8。

示例:

find -type f -name "*.txt" | while read file; do (file -i "$file"); done | awk -F[:=] '{print "iconv -f "$3" -t utf8 \""$1"\" > \""$1"_utf8\""}' | bash

答案 12 :(得分:0)

您可以使用file命令提取单个文件的编码。我有一个带有以下内容的sample.html文件:

$ file sample.html 

sample.html:HTML文档,UTF-8 Unicode文本,行很长

$ file -b sample.html

HTML文档,UTF-8 Unicode文本,行很长

$ file -bi sample.html

的text / html;字符集= UTF-8

$ file -bi sample.html  | awk -F'=' '{print $2 }'

UTF-8

答案 13 :(得分:0)

我正在使用以下脚本

  1. 找到所有与SIL_ENCODING匹配的FILTER文件
  2. 为其创建备份
  3. 将它们转换为DST_ENCODING
  4. (可选)删除备份

#!/bin/bash -xe

SRC_ENCODING="iso-8859-1"
DST_ENCODING="utf-8"
FILTER="*.java"

echo "Find all files that match the encoding $SRC_ENCODING and filter $FILTER"
FOUND_FILES=$(find . -iname "$FILTER" -exec file -i {} \; | grep "$SRC_ENCODING" | grep -Eo '^.*\.java')

for FILE in $FOUND_FILES ; do
    ORIGINAL_FILE="$FILE.$SRC_ENCODING.bkp"
    echo "Backup original file to $ORIGINAL_FILE"
    mv "$FILE" "$ORIGINAL_FILE"

    echo "converting $FILE from $SRC_ENCODING to $DST_ENCODING"
    iconv -f "$SRC_ENCODING" -t "$DST_ENCODING" "$ORIGINAL_FILE" -o "$FILE"
done

echo "Deleting backups"
find . -iname "*.$SRC_ENCODING.bkp" -exec rm {} \;

答案 14 :(得分:0)

在php中,您可以像下面这样检查:

明确指定编码列表:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

更准确的“ mb_list_encodings”:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

在第一个示例中,您可以看到我放置了可能匹配的编码列表(检测列表顺序)。 为了获得更准确的结果,您可以通过以下方式使用所有可能的编码: mb_list_encodings()

请注意mb_ *函数需要php-mbstring

apt-get install php-mbstring

答案 15 :(得分:0)

使用以下命令:

for f in `find .`; do echo `file -i "$f"`; done

您可以列出目录和子目录中的所有文件以及相应的编码。

答案 16 :(得分:-2)

使用Perl,使用Encode :: Detect。