Pergunta

Eu preciso encontrar a codificação de todos os arquivos que são colocados em um diretório. Existe uma maneira de encontrar a codificação usada?

O comando file não é capaz de fazer isso.

A codificação que é de interesse para mim é: ISO-8859-1. Se a codificação é qualquer outra coisa, eu quero mover o arquivo para outro diretório.

Foi útil?

Solução

Parece que você está procurando enca. Ele pode adivinhar e até mesmo converter entre codificações. Basta olhar para a página homem .

Ou, na sua falta, o uso file -i (linux) ou file -I (OSX). Que o produto será informações do tipo MIME para o arquivo, que também incluirá a codificação de caracteres-set. Eu encontrei um man-page por isso, também:)

Outras dicas

file -bi <file name>

Se você gostaria de fazer isso por um monte de arquivos

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

uchardet - uma codificação biblioteca detector portado do Mozilla

.

Uso:

~> uchardet file.java 
UTF-8

Várias distribuições Linux (Debian / Ubuntu, OpenSuse-packman, ...) fornecer binários.

aqui é um exemplo de script usando -I arquivo e iconv que trabalha em MacOSX Para a sua pergunta que você precisa usar mv vez de 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

É muito difícil determinar se é iso-8859-1. Se você tem um texto com apenas 7 bit caracteres que também poderia ser iso-8859-1, mas você não sabe. Se você tem 8 caracteres bit, em seguida, existem os personagens região superior em codificações de ordem também. Porém você teria que usar um dicionário para obter uma melhor adivinhar qual palavra é e determinar a partir daí que carta que deve ser. Finalmente, se você detectar que poderia ser utf-8 do que você tem certeza que não é iso-8859-1

A codificação é uma das coisas mais difíceis de fazer porque você nunca sabe se nada está lhe dizendo

Com Python, você pode usar o módulo chardet: https://github.com/chardet/chardet

No Debian você também pode usar: encguess:

$ encguess test.txt
test.txt  US-ASCII

Isto não é algo que você pode fazer em uma maneira infalível. Uma possibilidade seria examinar cada personagem no arquivo para garantir que ele não contém quaisquer caracteres no 0x00 - 0x1f faixas ou 0x7f -0x9f mas, como eu disse, isso pode ser verdade para qualquer número de arquivos, incluindo pelo menos uma outra variante do ISO8859.

Outra possibilidade é procurar palavras específicas no arquivo em todos os idiomas suportados e veja se você pode encontrá-los.

Assim, por exemplo, encontrar o equivalente do Inglês "e", "mas", "a", "de" e assim por diante em todas as línguas suportadas do 8859-1 e ver se eles têm um grande número de ocorrências dentro do arquivo.

Eu não estou falando sobre tradução literal, tais como:

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

apesar de que é possível. Estou falando de palavras na língua-alvo (pelo que sei, islandês não tem nenhuma palavra para "e" - você provavelmente teria que usar sua palavra para "peixe" [desculpa que é um pouco estereotipada, eu não fiz significa qualquer ofensa, apenas ilustrando um ponto]).

Se você está falando de arquivos XML (ISO-8859-1), o XML-declaração dentro deles especifica a codificação: <?xml version="1.0" encoding="ISO-8859-1" ?>
Assim, você pode usar expressões regulares (por exemplo, com perl) para verificar todos os arquivos para tal especificação.
Mais informações podem ser encontradas aqui: Como determinar arquivo de texto codificação .

Para converter codificar a partir de 8859 para ASCII:

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

Eu sei que você está interessado em uma resposta mais geral, mas o que é bom em ASCII é geralmente bom em outras codificações. Aqui é um Python one-liner para determinar se a entrada padrão é ASCII. (Eu tenho certeza que isso funciona em Python 2, mas eu só testei em 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

Em Cygwin, isso parece que funciona para mim:

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

Exemplo:

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

Você poderia tubo que a awk e criar um comando iconv para converter tudo para utf8, a partir de qualquer fonte de codificação suportada por iconv.

Exemplo:

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

Você pode extrair codificação de um único arquivo com o comando de arquivo. Eu tenho um arquivo sample.html com:

$ file sample.html 

sample.html: documento HTML, UTF-8 Unicode texto, com linhas muito longas

$ file -b sample.html

HTML documento, UTF-8 texto Unicode, com linhas muito longas

$ file -bi sample.html

text / html; charset = utf-8

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

utf-8

Eu estou usando o seguinte script para

  1. Encontre todos os arquivos que correspondem FILTER com SRC_ENCODING
  2. Criar um backup deles
  3. convertê-los para DST_ENCODING
  4. (opcional) Retire os backups

.

#!/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 {} \;

Com Perl, uso Encode :: Detectar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top