Как узнать кодировка файла в Unix через скрипт(ы)

Мне нужно найти кодировку всех файлов, которые помещены в каталог. Есть ли способ найти используемую кодировку?

на не в состоянии сделать это.

кодировка, представляющая для меня интерес: ISO-8859-1. Если кодировка-это что-то еще, я хочу переместить файл в другой каталог.

14 ответов


звучит так, как будто вы ищете enca. Он может угадывать и даже конвертировать между кодировками. Просто посмотрите на man page.

или, в противном случае, используйте file -i (linux) или file -I (osx). Это выведет информацию типа MIME для файла, которая также будет включать кодировку набора символов. Я нашел man-page за это тоже :)


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,...) предоставляем файлы.


вот пример скрипта с использованием file-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

кодировка это одна из самых сложных вещей, потому что вы никогда не знаете, если ничего не говорит вам


Если вы говорите о XML-файлах (ISO-8859-1), XML-декларация внутри них указывает кодировку: <?xml version="1.0" encoding="ISO-8859-1" ?>
Таким образом, вы можете использовать регулярные выражения (например,perl), чтобы проверить каждый файл по такой спецификации.
Более подробную информацию можно найти здесь: как определить кодировку текстового файла.


с Python вы можете использовать модуль chardet:https://github.com/chardet/chardet


Это не то, что вы можете сделать в надежный способ. Одной из возможностей было бы изучить каждый символ в файле, чтобы убедиться, что он не содержит символов в диапазонах 0x00 - 0x1f или 0x7f -0x9f но, как я уже сказал, это может быть верно для любого количества файлов, включая по крайней мере один другой вариант ISO8859.

еще одна возможность-искать определенные слова в файле на всех поддерживаемых языках и посмотреть, сможете ли вы их найти.

Так, например, найдите эквивалент английского "and", "but", "to", " of " и так далее на всех поддерживаемых языках 8859-1 и посмотрите, есть ли у них большое количество вхождений в файле.

Я не говорю о дословном переводе, например:

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

хотя это возможно. Я говорю об общих словах в целевом языке (насколько я знаю, в исландском нет слова "и" - вам, вероятно, придется использовать их слово для "рыбы" [извините, это немного стереотипно, я никого не хотел обидеть, просто картинки]).


Я знаю, что вас интересует более общий ответ, но то, что хорошо в 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 для преобразования всего в utf8 из любой исходной кодировки, поддерживаемой iconv.

пример:

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

в Debian вы также можете использовать: encguess:

$ encguess test.txt
test.txt  US-ASCII

вы можете извлечь кодировку одного файла с помощью команды file. У меня есть образец.HTML-файл с:

$ file sample.html 

образец.html: HTML документ, UTF - 8 Unicode текст, с очень длинными строками

$ file -b sample.html

HTML документ, UTF - 8 Unicode текст, с очень длинными строками

$ file -bi sample.html

text / html; charset=utf-8

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

кодировка UTF-8


Я использую следующий скрипт

  1. найти все файлы, которые соответствуют фильтру с SRC_ENCODING
  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 {} \;

с Perl используйте Encode:: Detect.