Domanda

Devo trovare la codifica di tutti i file che sono inseriti in una directory. C'è un modo per trovare la codifica utilizzata?

Il comando file non è in grado di farlo.

La codifica che mi interessa è: ISO-8859-1. Se la codifica è qualcos'altro, voglio spostare il file in un'altra directory.

È stato utile?

Soluzione

Sembra che tu stia cercando enca. Può indovinare e persino convertire tra codifiche. Guarda la pagina man .

Oppure, in mancanza, utilizzare file -i (linux) o file -I (osx). Ciò genererà informazioni di tipo MIME per il file, che includerà anche la codifica del set di caratteri. Ho trovato anche una man-page anche per questo :)

Altri suggerimenti

file -bi <file name>

Se ti piace farlo per un mucchio di file

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

uchardet - Una libreria di rilevatori di codifica trasferita da Mozilla.

Utilizzo:

~> uchardet file.java 
UTF-8

Varie distribuzioni Linux (Debian / Ubuntu, OpenSuse-packman, ...) forniscono file binari.

ecco uno script di esempio che utilizza il file -I e iconv che funziona su MacOsX Per la tua domanda devi usare mv invece di 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

È davvero difficile determinare se è iso-8859-1. Se hai un testo con soli caratteri a 7 bit che potrebbe anche essere iso-8859-1 ma non lo sai. Se si dispone di caratteri a 8 bit, esistono anche i caratteri della regione superiore anche nelle codifiche dell'ordine. Quindi dovresti usare un dizionario per capire meglio quale parola sia e determinare da lì quale lettera deve essere. Infine, se rilevi che potrebbe essere utf-8 di quanto sei sicuro che non sia iso-8859-1

La codifica è una delle cose più difficili da fare perché non si sa mai se nulla ti dice

Con Python puoi utilizzare il modulo chardet: https://github.com/chardet/chardet

In Debian puoi anche usare: encguess:

$ encguess test.txt
test.txt  US-ASCII

Questo non è qualcosa che puoi fare in modo infallibile. Una possibilità sarebbe quella di esaminare tutti i caratteri nel file per assicurarsi che non contenga caratteri negli intervalli 0x00 - 0x1f o 0x7f -0x9f ma, come ho detto, questo può essere vero per qualsiasi numero di file, incluso almeno un'altra variante di ISO8859.

Un'altra possibilità è cercare parole specifiche nel file in tutte le lingue supportate e vedere se riesci a trovarle.

Quindi, ad esempio, trova l'equivalente dell'inglese " e " ;, " ma " ;, " in " ;, " quot del &; e così via in tutte le lingue supportate di 8859-1 e vedere se hanno un gran numero di occorrenze all'interno del file.

Non sto parlando di una traduzione letterale come:

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

sebbene sia possibile. Sto parlando di parole comuni nella lingua di destinazione (per quanto ne so, l'islandese non ha parole per & Quot; e & Quot; - probabilmente dovresti usare la loro parola per & Quot; fish " [scusate se è un po 'stereotipato, non intendevo alcuna offesa, sto solo illustrando un punto]).

Se stai parlando di file XML (ISO-8859-1), la dichiarazione XML al loro interno specifica la codifica: <?xml version="1.0" encoding="ISO-8859-1" ?>
Pertanto, puoi utilizzare le espressioni regolari (ad es. Con perl) per controllare ogni file per tale specifica.
Ulteriori informazioni sono disponibili qui: Come determinare la codifica dei file di testo .

Per convertire la codifica da 8859 a ASCII:

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

So che sei interessato a una risposta più generale, ma ciò che è buono in ASCII di solito è buono in altre codifiche. Ecco un one-liner Python per determinare se l'input standard è ASCII. (Sono abbastanza sicuro che funzioni in Python 2, ma l'ho provato solo su 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

In Cygwin, sembra che funzioni per me:

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

Esempio:

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

Potresti reindirizzarlo a awk e creare un comando iconv per convertire tutto in utf8, da qualsiasi codifica sorgente supportata da iconv.

Esempio:

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

Puoi estrarre la codifica di un singolo file con il comando file. Ho un file sample.html con:

$ file sample.html 

sample.html: documento HTML, testo Unicode UTF-8, con righe molto lunghe

$ file -b sample.html

Documento HTML, testo Unicode UTF-8, con righe molto lunghe

$ file -bi sample.html

text / html; charset = utf-8

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

UTF-8

Sto usando il seguente script per

  1. Trova tutti i file che corrispondono a FILTER con SRC_ENCODING
  2. Creane un backup
  3. Convertili in DST_ENCODING
  4. (opzionale) Rimuovi i backup

.

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

Con Perl, utilizzare Encode :: Detect.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top