如何通过脚本在Unix中找到文件的编码
题
我需要找到放在目录中的所有文件的编码。有没有办法找到使用的编码?
file
命令无法执行此操作。
我感兴趣的编码是:ISO-8859-1。如果编码是其他任何东西,我想将文件移动到另一个目录。
其他提示
file -bi <file name>
如果您喜欢为一堆文件执行此操作
for f in `find | egrep -v Eliminate`; do echo "$f" ' -- ' `file -bi "$f"` ; done
uchardet - 从Mozilla移植的编码检测器库。
用法:
~> uchardet file.java
UTF-8
各种Linux发行版(Debian / Ubuntu,OpenSuse-packman,...)提供二进制文件。
这是一个使用文件-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
确定它是否是iso-8859-1真的很难。如果你的文本只有7位字符,也可能是iso-8859-1,但你不知道。如果您有8位字符,那么上面区域字符也存在于顺序编码中。因此,您必须使用字典来更好地猜测它是哪个单词,并从那里确定它必须是哪个字母。最后,如果你发现它可能是utf-8而不是你确定它不是iso-8859-1
编码是最困难的事情之一,因为你永远不知道是否有什么东西告诉你
使用Python,您可以使用chardet模块: https://github.com/chardet/chardet
在Debian中你也可以使用:encguess
:
$ encguess test.txt
test.txt US-ASCII
这不是你能以万无一失的方式做的事情。一种可能性是检查文件中的每个字符以确保它不包含0x00 - 0x1f
或0x7f -0x9f
范围内的任何字符,但正如我所说,对于任何数量的文件都可能是这样,包括至少包括ISO8859的另一个变体。
另一种可能性是在所有支持的语言中查找文件中的特定单词,看看是否可以找到它们。
因此,例如,找到相当于英语<!>“和<!>”;,<!>“;但是<!>”,<!>“到<!>”; <!> QUOT; <!> QUOT的;在所有支持的8859-1语言中等等,看看它们是否在文件中出现大量事件。
我不是在谈论字面翻译,例如:
English French
------- ------
of de, du
and et
the le, la, les
虽然这是可能的。我正在谈论目标语言中的常用词(据我所知,冰岛语中没有<!>引用词和<!>引用词) - 你可能不得不将它们的词用于<!> quot; fish <!>; [抱歉这有点刻板,我并不是指任何冒犯,只是说明了一点]。
如果您正在谈论XML文件(ISO-8859-1),其中的XML声明指定了编码:<?xml version="1.0" encoding="ISO-8859-1" ?>
因此,您可以使用正则表达式(例如,使用perl
)来检查每个文件是否符合此类规范
更多信息可以在这里找到:如何确定文本文件编码。
将编码从8859转换为ASCII:
iconv -f ISO_8859-1 -t ASCII filename.txt
我知道你对更一般的答案很感兴趣,但是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
在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
您可以使用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
我正在使用以下脚本
- 查找与SRTER匹配的所有文件与SRC_ENCODING
- 创建它们的备份
- 将它们转换为DST_ENCODING
- (可选)删除备份 醇>
#!/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 {} \;
使用Perl,使用Encode :: Detect。