Najlepszy sposób na konwersję plików tekstowych między zestawami znaków?

526

Jakie jest najszybsze, najłatwiejsze narzędzie lub metoda konwersji plików tekstowych między zestawami znaków?

W szczególności muszę przekonwertować z UTF-8 na ISO-8859-15 i odwrotnie.

Wszystko idzie: jednowierszowe w Twoim ulubionym języku skryptowym, narzędzia wiersza poleceń lub inne narzędzia do systemu operacyjnego, stron internetowych itp.

Najlepsze rozwiązania do tej pory:

W systemach Linux / UNIX / OS X / cygwin:

  • Gnu iconv sugerowany przez Troelsa Arvina najlepiej stosować jako filtr . Wydaje się być powszechnie dostępny. Przykład:

    $ iconv -f UTF-8 -t ISO-8859-15 in.txt > out.txt
    

    Jak zauważył Ben , istnieje internetowy konwerter wykorzystujący iconv .

  • Recode Gnu ( ręczne ) sugerowane przez Cheekysoft przekonwertuje jeden lub kilka plików w miejscu . Przykład:

    $ recode UTF8..ISO-8859-15 in.txt
    

    Ten używa krótszych aliasów:

    $ recode utf8..l9 in.txt
    

    Recode obsługuje również powierzchnie, które można wykorzystać do konwersji między różnymi typami zakończeń linii i kodowaniem:

    Konwertuj znaki nowej linii z LF (Unix) na CR-LF (DOS):

    $ recode ../CR-LF in.txt
    

    Plik kodowania Base64:

    $ recode ../Base64 in.txt
    

    Możesz je również łączyć.

    Konwertuj plik UTF8 zakodowany w Base64 z zakończeniami linii Unix na plik Latin 1 w formacie Base64 z zakończeniami linii Dos:

    $ recode utf8/Base64..l1/CR-LF/Base64 file.txt
    

W systemie Windows z Powershell ( Jay Bazuzi ):

  • PS C:\> gc -en utf8 in.txt | Out-File -en ascii out.txt

    (Brak obsługi ISO-8859-15; mówi, że obsługiwane zestawy znaków to Unicode, UTF7, UTF8, UT32, ASCII, Bigendianunicode, domyślny i OEM).

Edytować

Czy masz na myśli wsparcie iso-8859-1? Użycie „String” robi to np. Na odwrót

gc -en string in.txt | Out-File -en utf8 out.txt

Uwaga: Możliwe wartości wyliczeń to „Nieznany, Ciąg, Unicode, Bajt, BigEndianUnicode, UTF8, UTF7, Ascii”.

Antti Sykäri
źródło
Próbowałem, gc -en Ascii readme.html | Out-File -en UTF8 readme.htmlale konwertuje plik do utf-8, ale potem jest pusty! Notepad ++ mówi, że plik ma format Ansi, ale czytam, bo rozumiem, że to nawet nie jest prawidłowy zestaw znaków? uk.answers.yahoo.com/question/index?qid=20100927014115AAiRExF
OZZIE
2
Wystarczy natknąć się na to, szukając odpowiedzi na powiązane pytanie - świetne podsumowanie! Pomyślałem, że warto dodać, że recodezadziała również jako filtr, jeśli nie podasz żadnych nazw plików, np .:recode utf8..l9 < in.txt > out.txt
Jez
iconv.com/iconv.htm wydaje mi się martwy? (limit czasu)
Andrew Newby
2
Jeśli używasz enca, nie musisz określać kodowania wejściowego. Jest to na tyle często, żeby określić język: enca -L ru -x utf8 FILE.TXT.
Alexander Pozdneev
1
W rzeczywistości iconv działał znacznie lepiej jako konwerter lokalny zamiast filtra. Konwersja pliku zawierającego ponad 2 miliony linii przy użyciu iconv -f UTF-32 -t UTF-8 input.csv > output.csvzapisanych tylko około siedmiuset tysięcy linii, tylko jedna trzecia. Za pomocą wersji iconv -f UTF-32 -t UTF-8 file.csvlokalnej udało się przekonwertować wszystkie 2 miliony linii plus.
Nicolay77

Odpowiedzi:

246

Samodzielne podejście do użyteczności

iconv -f ISO-8859-1 -t UTF-8 in.txt > out.txt
-f ENCODING  the encoding of the input
-t ENCODING  the encoding of the output

Nie musisz podawać żadnego z tych argumentów. Będą domyślnie ustawione na bieżące ustawienia regionalne, którymi zwykle jest UTF-8.

Troels Arvin
źródło
4
Dla każdego, kto jest zaskoczony tym, że wersje nie-kreskowe są niedostępne, wygląda na to, że OSV (i prawdopodobnie wszystkie BSD) wersje iconv nie obsługują aliasów nie-kreskowych dla różnych kodowań UTF- *. iconv -l | grep UTFpoinformuje cię o wszystkich kodowaniach związanych z UTF, które obsługuje twoja kopia iconv.
coredumperror
14
Nie znasz kodowania pliku wejściowego? Służy chardet in.txtdo generowania najlepszego odgadnięcia. Wynik można wykorzystać jako ENCODING w iconv -f ENCODING.
Gulasz
4
Zapobiegać zjazd na nieprawidłowych znaków (unikanie illegal input sequence at positionwiadomości) i zastąpić „weird” znaki z „podobny” znaków: iconv -c -f UTF-8 -t ISO-8859-1//TRANSLIT in.txt > out.txt.
knb
Podoba mi się to, ponieważ jest standardem na większości platform NIX. Ale również zobaczyć opcję polecenia VIM (alias: ex) poniżej . Informacje dodatkowe: (1) Ty (prawdopodobnie) nie musisz określać opcji -f(od) za pomocą iconv. (2) file --mime-encoding <file/s>polecenie może pomóc w zrozumieniu kodowania.
fr13d
1
FWIW filepolecenie zgłosiło moje źródło jako UTF-16 Little Endian; uruchomione iconv -f UTF-16 -t UTF-8...przekształciło go niepoprawnie do ASCII, musiałem jawnie określić, iconv -f UTF-16LE...aby wyprowadzić UTF-8
Plato
90

Wypróbuj VIM

Jeśli tak vim, możesz użyć tego:

Nie testowane dla każdego kodowania.

Fajne jest to, że nie musisz znać kodowania źródłowego

vim +"set nobomb | set fenc=utf8 | x" filename.txt

Pamiętaj, że to polecenie bezpośrednio modyfikuje plik


Część wyjaśniająca!

  1. +: Używany przez vima do bezpośredniego wprowadzenia polecenia podczas otwierania pliku. Zwykle używany do otwierania pliku w określonym wierszu:vim +14 file.txt
  2. |: Separator wielu poleceń (jak ;w bash)
  3. set nobomb : brak BOM utf-8
  4. set fenc=utf8: Ustaw nowe kodowanie na link do dokumentu utf-8
  5. x : Zapisz i zamknij plik
  6. filename.txt : ścieżka do pliku
  7. ": cytaty są tutaj z powodu potoków. (w przeciwnym razie bash użyje ich jako rury bash)
doładowania
źródło
Całkiem fajne, ale nieco powolne. Czy istnieje sposób, aby to zmienić, aby przekonwertować wiele plików jednocześnie (co pozwala zaoszczędzić na kosztach inicjalizacji vima)?
DomQ,
Dziękuję za wyjaśnienie! Miałem trudności z początkiem pliku, dopóki nie przeczytałem o ustawieniu bomby / nobomb.
jjwdesign
1
np. dodatkowo możesz zobaczyć bom, jeśli używasz vim -blubhead file.txt|cat -e
Boop
1
na przykład:find -regextype posix-extended -type f -regex ".*\.(h|cpp|rc|fx|cs|props|xaml)" -exec vim +'set nobomb | set fenc=utf8 | x' {} \;
Gabriel
Użyłem tego do konwersji kodowania plików CSV i byłem naprawdę podekscytowany, gdy zobaczyłem, że zestaw znaków rzeczywiście się zmienił. Niestety, kiedy poszedłem załadować plik do MySQL, miał on inną liczbę kolumn niż poprzednio, zanim uruchomiłem polecenie vim. Zastanawiasz się, czy można po prostu otworzyć plik, przekonwertować kodowanie i zapisać / zamknąć plik, pozostawiając tę ​​samą zawartość pliku?
NightOwlPrgmr
39

Pod Linuksem możesz użyć bardzo wydajnej komendy recode, aby spróbować konwertować różne zestawy znaków, a także wszelkie problemy z zakończeniem linii. recode -l pokaże wszystkie formaty i kodowania, między którymi narzędzie może konwertować. Prawdopodobnie będzie to BARDZO długa lista.

Cheekysoft
źródło
Jak się przekonwertować LF? Jest /CRi /CR-LFnie ma/LF
Aaron Franke
21

iconv (1)

iconv -f FROM-ENCODING -t TO-ENCODING file.txt

Istnieją również narzędzia oparte na iconv w wielu językach.

Daniel Papasian
źródło
1
Co z automatycznym wykrywaniem oryginalnego kodowania?
Aaron Franke
20
Get-Content -Encoding UTF8 FILE-UTF8.TXT | Out-File -Encoding UTF7 FILE-UTF7.TXT

Najkrótsza wersja, jeśli możesz założyć, że BOM wejściowy jest poprawny:

gc FILE.TXT | Out-File -en utf7 file-utf7.txt
Jay Bazuzi
źródło
1
Oto krótsza wersja, która działa lepiej. gc .\file-utf8.txt | sc -en utf7 .\file-utf7.txt
Larry Battle,
@LarryBattle: Jak Set-Contentdziała lepiej niż Out-File?
Jay Bazuzi,
...O. Myślę, że są prawie takie same. Miałem problem z uruchomieniem twojego przykładu, ponieważ zakładałem, że obie wersje używają tego samego file-utf8.txtpliku do wprowadzania danych, ponieważ obie miały taki sam plik wyjściowy jak file-utf7.txt.
Larry Battle,
Byłoby to naprawdę świetne, poza tym, że nie obsługuje UTF16. Obsługuje UTF32, ale nie UTF16! Nie musiałbym konwertować plików, z wyjątkiem tego, że wiele programów Microsoft (np. SQL Server bcp) nalega na UTF16 - a wtedy ich narzędzie nie przekonwertuje się na to. Ciekawe co najmniej.
Noah,
Próbowałem, gc -en Ascii readme.html | Out-File -en UTF8 readme.htmlale konwertuje plik do utf-8, ale potem jest pusty! Notepad ++ mówi, że plik ma format Ansi, ale czytam, bo rozumiem, że to nawet nie jest prawidłowy zestaw znaków? uk.answers.yahoo.com/question/index?qid=20100927014115AAiRExF
OZZIE
16

Wypróbuj funkcję Bash iconv

Umieściłem to w .bashrc:

utf8()
{
    iconv -f ISO-8859-1 -t UTF-8 $1 > $1.tmp
    rm $1
    mv $1.tmp $1
}

.. aby móc konwertować pliki w taki sposób:

utf8 MyClass.java
Arne Evertsson
źródło
8
lepiej jest użyć tmp = $ (mktmp) do utworzenia pliku tymczasowego. Ponadto linia z rm jest zbędna.
LMZ
1
czy możesz uzupełnić tę funkcję o format automatycznego wykrywania?
mlibre
3
Uwaga, ta funkcja usuwa plik wejściowy bez sprawdzenia, czy wywołanie iconv zakończyło się powodzeniem.
philwalk
Zmienia to zawartość pliku tekstowego. Uruchomiłem to na UTF-8 z BOM, spodziewając się, że wyjdę z UTF-8 bez pliku BOM, ale poprzedziło to na początku pliku.
Aaron Franke
14

Wypróbuj Notepad ++

W systemie Windows mogłem użyć Notepad ++ do konwersji z ISO-8859-1 na UTF-8 . Kliknij, "Encoding"a następnie "Convert to UTF-8".

Jeremy Glover
źródło
13

Oneliner używa find, z automatycznym wykrywaniem zestawu znaków

Kodowanie znaków wszystkich pasujących plików tekstowych jest wykrywane automatycznie, a wszystkie pasujące pliki tekstowe są konwertowane na utf-8kodowanie:

$ find . -type f -iname *.txt -exec sh -c 'iconv -f $(file -bi "$1" |sed -e "s/.*[ ]charset=//") -t utf-8 -o converted "$1" && mv converted "$1"' -- {} \;

W celu przeprowadzenia tych etapów podpowłoki shjest używany -exec, prowadzenie jedną wkładkę z -cflagą i przepuszczenie pliku jako argumentu położenia "$1"z -- {}. W międzyczasie utf-8plik wyjściowy ma tymczasową nazwę converted.

W ten file -bisposób oznacza:

  • -b, --brief Nie dołączaj nazw plików do linii wyjściowych (tryb skrócony).

  • -i, --mime Powoduje, że komenda file wyświetla łańcuchy znaków typu MIME, a nie bardziej tradycyjne, czytelne dla człowieka. Dlatego może powiedzieć na przykład text/plain; charset=us-asciizamiast ASCII text. Te sedkawałki tego polecenia, aby tylko us-asciijak jest to wymagane przez iconv.

findKomenda jest bardzo użyteczna dla takiej automatyzacji zarządzania plikami. Kliknij tutaj, aby uzyskać więcej findobfitości .

Serge Stroobandt
źródło
3
Musiałem trochę dostosować to rozwiązanie, aby działało w systemie Mac OS X, przynajmniej w mojej wersji. find . -type f -iname *.txt -exec sh -c 'iconv -f $(file -b --mime-encoding "$1" | awk "{print toupper(\$0)}") -t UTF-8 > converted "$1" && mv converted "$1"' -- {} \;
Brian J. Miller,
1
Twój kod działał również w systemie Windows 7 z MinGW-w64 (najnowsza wersja). Dziękujemy za udostępnienie!
silvioprog,
@rmuller sedPolecenie jest tam celowe, umożliwiając automatyczne wykrywanie kodowania znaków. Rozszerzyłem odpowiedź, aby wyjaśnić to teraz. Uprzejmie byłoby w przypadku czytelników usunięcie wszelkich nieistotnych komentarzy. Dziękuję Ci.
Serge Stroobandt
@SergeStroobandt Może nie byłem wystarczająco jasny. Chodzi mi o to, że kiedy używasz „file -b --mime-encoding” zamiast „file -bi”, nie ma potrzeby filtrowania wyniku za pomocą sed. To polecenie już zwraca tylko kodowanie pliku. Więc w twoim przykładzie „us-ascii”
rmuller
Wydaje się, że tak naprawdę nie robi to nic dla mnie w systemie Linux. Zapisałem plik jako UTF-8 z BOM i spodziewałem się, że skonwertuje się na UTF-8 bez BOM i tak się nie stało.
Aaron Franke
3

PHP iconv ()

iconv("UTF-8", "ISO-8859-15", $input);

użytkownik15096
źródło
1
Ta instrukcja działa świetnie podczas konwersji ciągów, ale nie w przypadku plików.
jjwdesign
2

DOS / Windows: użyj strony kodowej

chcp 65001>NUL
type ascii.txt > unicode.txt

Polecenia chcpmożna użyć do zmiany strony kodowej. Strona kodowa 65001 to nazwa Microsoft dla UTF-8. Po ustawieniu strony kodowej dane wyjściowe wygenerowane przez następujące polecenia będą ustawione na stronie kodowej.

lalthomas
źródło
1

do pisania pliku właściwości (Java) zwykle używam tego w systemie Linux (dystrybucje mint i ubuntu):

$ native2ascii filename.properties

Na przykład:

$ cat test.properties 
first=Execução número um
second=Execução número dois

$ native2ascii test.properties 
first=Execu\u00e7\u00e3o n\u00famero um
second=Execu\u00e7\u00e3o n\u00famero dois

PS: Napisałem Wykonanie numer jeden / dwa w Portugalii, aby wymusić znaki specjalne.

W moim przypadku przy pierwszym wykonaniu otrzymałem ten komunikat:

$ native2ascii teste.txt 
The program 'native2ascii' can be found in the following packages:
 * gcj-5-jdk
 * openjdk-8-jdk-headless
 * gcj-4.8-jdk
 * gcj-4.9-jdk
Try: sudo apt install <selected package>

Kiedy zainstalowałem pierwszą opcję (gcj-5-jdk) problem został zakończony.

Mam nadzieję, że komuś to pomoże.

Maciel Bombonato
źródło
0

Moim ulubionym narzędziem do tego jest Jedit (edytor tekstowy oparty na Javie), który ma dwie bardzo wygodne funkcje:

  • Jeden, który pozwala użytkownikowi ponownie załadować tekst z innym kodowaniem (i jako taki, kontrolować wizualnie wynik)
  • Kolejny, który umożliwia użytkownikowi jawne wybranie kodowania (i znaku końca linii) przed zapisaniem
yota
źródło
0

Wystarczy zmienić kodowanie załadowanego pliku w IntelliJ IDEA IDE, po prawej stronie paska stanu (u dołu), gdzie wskazany jest aktualny zestaw znaków. Wyświetla monit o ponowne załadowanie lub konwersję, użyj Konwertuj. Należy wcześniej wykonać kopię zapasową oryginalnego pliku.

Nikołaj Varankine
źródło
0

Jeśli aplikacje macOS GUI to Twój chleb powszedni, SubEthaEdit to edytor tekstowy, do którego zwykle chodzę w celu zakodowania kodowania - jego „podgląd konwersji” pozwala zobaczyć wszystkie nieprawidłowe znaki w kodowaniu wyjściowym i je naprawić / usunąć.

I jest teraz open source , więc tak dla nich for.

tiennou
źródło