Domanda

Ho copiato alcuni file da una macchina Windows a una macchina Linux. Quindi, tutti i file di Windows codificato (windows-1252) devono essere convertiti in UTF-8. I file che sono già in UTF-8 non dovrebbero essere modificate. Sto pensando di utilizzare l'utilità recode per questo. Come è possibile specificare che l'utilità recode dovrebbe convertire solo i file codificati windows-1252 e non i UTF-8 file?

Esempio di utilizzo di Recode:

recode windows-1252.. myfile.txt

Questo sarebbe convertire myfile.txt da windows-1252 a UTF-8. Prima di fare questo, vorrei sapere che è in realtà myfile.txt windows-1252 codificata e non codifica UTF-8. In caso contrario, credo che questo avrebbe corrotto il file.

È stato utile?

Soluzione

Come vi aspettate Recode sapere che un file è Windows-1252? In teoria, credo qualsiasi tipo di file è un file di Windows-1252 valida, in quanto le mappe ogni possibile byte per un carattere.

Ora ci sono certamente le caratteristiche che sarebbe fortemente suggerire che è UTF-8 - se inizia con l'UTF-8 BOM, per esempio - ma non sarebbero in definitiva

.

Una possibilità sarebbe quella di rilevare se in realtà è un file completamente valida UTF-8 prima, suppongo ... ancora una volta, che sarebbe solo suggestione.

Non ho dimestichezza con lo strumento recode in sé, ma si potrebbe desiderare di vedere se è in grado di ricodifica un file da e verso il stesso Codifica - se si esegue questa operazione con un file non valido ( cioè uno che contiene non validi UTF-8 sequenze di byte) si può ben convertire le sequenze non validi in punti interrogativi o qualcosa di simile. A quel punto si potrebbe rilevare che un file è valido UTF-8 da ricodifica a UTF-8 e di vedere se l'input e l'output sono identici.

In alternativa, fare questo a livello di codice, piuttosto che utilizzando l'utilità recode -. Sarebbe molto semplice in C #, ad esempio

Proprio per ribadire però: tutto questo è euristica. Se davvero non si conosce la codifica di un file, niente sta andando per dirvi che con il 100% di precisione.

Altri suggerimenti

è possibile utilizzare iconv:

iconv -f WINDOWS-1252 -t UTF-8 filename.txt

Ecco una trascrizione di un'altra risposta che ho dato a una domanda simile:

Se si applica utf8_encode () su una stringa già UTF8 tornerà un'uscita UTF8 confusa.

Ho fatto una funzione che affronta tutti questi problemi. E'chiamato Encoding :: toUTF8 ().

Non avete bisogno di sapere che la codifica delle corde è. Può essere Latin1 (iso 8859-1), Windows-1252 o UTF8, o la stringa può avere un mix di loro. Encoding :: toUTF8 () convertirà tutto per UTF8.

L'ho fatto perché un servizio mi stava dando un feed di dati di tutto incasinato, mescolando UTF8 e Latin1 nella stessa stringa.

Utilizzo:

$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);

$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);

Download:

https://github.com/neitanod/forceutf8

Aggiornamento:

Ho incluso un'altra funzione, Encoding :: fixUFT8 (), wich fisserà ogni stringa UTF8 che sembra confusa.

Utilizzo:

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);

Esempi:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");

visualizzerà:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football

Aggiornamento: Ho trasformato la funzione (forceUTF8) in una famiglia di funzioni statiche su una classe chiamata codifica. La nuova funzione è Encoding :: toUTF8 ().

Non c'è modo generale per dire se un file è codificato con una codifica specifica. Ricordate che una codifica non è altro che un "accordo" come i bit in un file devono essere mappati a caratteri.

Se non si sa quale dei tuoi file sono in realtà già codificato in UTF-8 e quelli che sono codificati in windows-1252, si dovrà esaminare tutti i file e scoprire da soli. Nel peggiore dei casi che potrebbe significare che si deve aprire ogni singolo uno di loro con una delle due codifiche e vedere se "guardano" corretta - vale a dire, tutti i caratteri vengono visualizzati correttamente. Naturalmente, è possibile utilizzare strumento di supporto al fine di fare che, per esempio, se si sa per certo che alcuni caratteri sono contenuti nei file che hanno una mappatura diversa in windows-1252 vs UTF-8, si potrebbe grep per loro dopo aver eseguito i file tramite 'iconv' come detto da Seva Akekseyev.

Un altro caso fortunato per voi sarebbe, se si sa che i file in realtà contengono solo i caratteri che sono codificati in modo identico in entrambi i UTF-8 e Windows-1252. In questo caso, naturalmente, il gioco è fatto già.

Se si desidera rinominare più file in un unico comando - diciamo che si desidera convertire tutti i file *.txt - Ecco il comando:

find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;

Utilizzare il iconv di comando.

Per assicurarsi che il file si trova in Windows-1252, aprirlo nel Blocco note (in Windows), quindi fare clic su Salva con nome. Notepad suggerisce codifica corrente come default; se si tratta di Windows 1252 (o qualsiasi tabella codici 1 byte, se è per questo), si direbbe "ANSI".

È possibile modificare la codifica di un file con un editor come Notepad ++. Basta andare alla codifica e selezionare ciò che si desidera.

Io preferisco sempre Windows 1252

Se sei sicuro che i file sono UTF-8 o Windows 1252 (o Latin1), si può approfittare del fatto che Recode uscirà con un errore se si tenta di convertire un file non valido.

Mentre utf8 è valida Win-1252, il contrario non è vero: win-1252 non è valido UTF-8. Quindi:

recode utf8..utf16 <unknown.txt >/dev/null || recode cp1252..utf8 <unknown.txt >utf8-2.txt

Sarà sputare fuori gli errori per tutti i file CP1252, e quindi procedere a convertirli in UTF8.

Vorrei avvolgere questo in uno script bash più pulito, mantenendo una copia di backup di tutti i file convertito.

Prima di fare la conversione charset, si potrebbe desiderare di assicurarsi prima di avere consistenti line-terminazioni in tutti i file. In caso contrario, recode si lamenterà a causa di questo, e può convertire i file che erano già UTF8, ma appena avuto i sbagliate line-finali.

per il comando TYPE :

Convertire un ASCII (Windows1252) file in un file (UCS-2 le) testo Unicode:

For /f "tokens=2 delims=:" %%G in ('CHCP') do Set _codepage=%%G    
CHCP 1252 >NUL    
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > unicode.txt 2>NUL    
CMD.EXE /D /U /C TYPE ascii_file.txt >> unicode.txt    
CHCP %_codepage%    

La tecnica di cui sopra (sulla base di una sceneggiatura di Carlos M.) prima crea un file con un Byte Order Mark (BOM) e quindi aggiunge il contenuto del file originale. CHCP viene utilizzato per garantire la sessione è in esecuzione con la tabella codici Windows1252 modo che i caratteri 0xFF e 0xFE (YTH) vengano interpretati correttamente.

UTF-8 non ha una distinta in quanto è sia superfluo e non valida. Qualora una distinta base è utile è in UTF-16, che può essere byte scambiati, come nel caso di Microsoft. UTF-16 se per rappresentazione interna in un buffer di memoria. Utilizzare UTF-8 per l'interscambio. Per impostazione predefinita sia UTF-8, tutto il resto deriva da US-ASCII e UTF-16 sono byte order / naturale network. Il Microsoft UTF-16 richiede una distinta in quanto è di byte scambiati.

Per occulta di Windows-1252 a ISO8859-15, ho prima convertire ISO8859-1 a US-ASCII per i codici con glifi simili. Ho poi convertire windows-1252 fino a ISO8859-15, altri glifi non ISO8859-15 a più caratteri US-ASCII.

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