Jakie są różnice między plikami .txt systemu Linux i Windows (kodowanie Unicode)

16

Używam tylko zestawu znaków 128 zdefiniowanego w oryginalnym standardzie ANSI.

Ale jako całość pliki są różnie wszczepiane.

Nie interesuje mnie wyświetlanie, tzn. Czy karta jest wyświetlana z 6 lub 8 znakami, ale z faktyczną wewnętrzną reprezentacją w pamięci

Jedną z różnic, jakie słyszałem, jest użycie \ r \ n (Windows) vs. \ n do zakończenia linii (Linux).

Hennes
źródło
Myślę, że znak kolejności bajtów zabija mój #! (Pierwszy wiersz) w moich plikach php, które przesłałem z systemu Windows do systemu Linux. Cały plik działa, ale nie może znaleźć interpretera tak, jak powinien. Gdybym specefically upewnij się do kodowania ANSI wybierając metodę kodowania w notatniku czy to prawda, czy też ASCII systemu Windows zrobić coś innego
Sprawdź, czy masz bombardowanie na swoim urządzeniu Gnu / Linux. Jest częścią Debiana (i przynajmniej niektórych innych), ale może wymagać instalacji. Jest to potrzebne, ponieważ Microsoft błędnie dodaje BOM na początku plików utf-8.
ctrl-alt-delor

Odpowiedzi:

17

„Unicode” w systemie Windows to UTF-16LE, a każdy znak ma 2 lub 4 bajty. Linux używa UTF-8, a każdy znak ma od 1 do 4 bajtów.

„Absolutne minimum Każdy twórca oprogramowania absolutnie, pozytywnie musi wiedzieć o Unicode i zestawach znaków (bez wymówek!)”

Ignacio Vazquez-Abrams
źródło
Windows marnuje bajt?
1
Jeśli nie używasz niczego poza Latin-1, tak.
Ignacio Vazquez-Abrams,
Są w artykule, do którego linkowałem.
Ignacio Vazquez-Abrams,
1
Rozpocząłem wyszukiwanie UTF-16LE, ale nie znalazłem go w artykule.
1
Przeważnie. Musisz także policzyć BOM, jeśli jest obecny.
Ignacio Vazquez-Abrams,
11

Podziały wierszy

Windows używa zakończeń linii CRLF ( \r\n, 0D 0A), podczas gdy Unix używa tylko LF ( \n, 0A).

Kodowanie znaków

Większość współczesnych (tj. Od 2004 roku) systemów uniksowych sprawia, że UTF-8 jest domyślnym kodowaniem znaków.

Windows jednak nie ma natywnego wsparcia dla UTF-8. Działa wewnętrznie w UTF-16 i zakłada, że charłańcuchy oparte na starszej stronie kodowej . Na szczęście Notatnik może odczytywać pliki UTF-8; niestety kodowanie „ANSI” jest nadal domyślne.

Problematyczne znaki specjalne

U + 001A SUBSTYTUT

Windows (rzadko) używa Ctrl+ Zjako znaku końca pliku. Na przykład, jeśli typeplik znajduje się w wierszu polecenia, zostanie obcięty w pierwszym 1Abajcie.

W Uniksie Ctrl+ Znie jest niczym specjalnym.

U + FEFF ZERO Z PRZESTRZEŃ BEZ PRZERWY (znak kolejności bajtów)

W systemie Windows pliki UTF-8 często zaczynają się od „znaku kolejności bajtów”, EF BB BFaby odróżnić je od plików ANSI.

W Linuksie BOM jest odradzany, ponieważ przerywa takie rzeczy, jak linie shebang w skryptach powłoki. Ponadto nie ma sensu mieć podpisu UTF-8, gdy UTF-8 jest i tak domyślnym kodowaniem.

użytkownik46971
źródło
1
Ctrl-Z działa w sttysystemie Windows, podobnie jak Ctrl-D (lub jakikolwiek znak, który przypisałeś do EOF ) w systemie Linux: sterownik konsoli tłumaczy go na koniec pliku. Dosłowny znak nie pojawia się w strumieniu wejściowym; po prostu powoduje, że read () zwraca 0.
psusi
Myślę, że znak kolejności bajtów zabija mój #! (Pierwszy wiersz) w moich plikach php, które przesłałem z systemu Windows do systemu Linux. Cały plik działa, ale nie może znaleźć interpretera tak, jak powinien. Jeśli konkretnie upewnij się, że koduję w ANSI, wybierając metodę kodowania w notatniku, czy jest to prawda ASCII, czy też Windows robi coś innego?
1
Warto wspomnieć, że pseudotermiczna „strona kodowa ANSI”, mimo że wciąż pojawia się w takich programach jak Notatnik, jest całkowicie błędna i Microsoft przyznał to dawno temu. Szczegółowe informacje można znaleźć na stronie en.wikipedia.org/wiki/Windows_code_page .
Incnis Mrsi,
utf-8 nie ma BOM, ale MS-Windows wstawia jeden. Czyni to nieprawdą utf-8. Jedną z zasad utf-8 jest to, że każdy plik, który może być reprezentowany w ascii, jest nieco identyczny w utf-8. Możesz także rozpocząć czytanie utf-8 w dowolnym punkcie strumienia.
ctrl-alt-delor
3

Jedną z różnic, jakie słyszałem, jest użycie \ r \ n (Windows) vs. \ n do podziału linii (Linux).

Tak. Większość edytorów tekstowych UNIX będzie to obsługiwać automatycznie, edytory dla programistów Windows mogą to obsłużyć, ogólne edytory tekstu (podstawowy Notatnik) nie.

Windows wydaje się także potrzebować EOF (Ctrl-Z) jako KONIEC PLIKU w niektórych kontekstach, podczas gdy prawdopodobnie nigdy go nie zobaczysz w systemie UNIX.

Pamiętaj, że MacOS X jest teraz pod UNIXem, więc używa zakończeń linii UNIX. Chociaż przed OS X (MacOS 9 i starsze) miał własne zakończenie (\ r)

EDYCJA: w innym formacie CR i LF:

  • \ n to ASCII 0x0A, przesunięcie wiersza (LF)
  • R jest ASCII 0x0D, powrót karetki (CR)
Rich Homolka
źródło
Gdzie są \ r \ n i \ n w zestawie znaków ASCII? en.wikipedia.org/wiki/File:ASCII_Code_Chart.svg
2
@Chris \ n to ASCII 0x0A, przesunięcie wiersza. jest ASCII 0x0D, Zwrot karetki
Rich Homolka
@Rich Co z EOF? Czy to znak ANSI?
2
@barlop, terminal tłumaczy naciśnięcie klawisza (zwykle jest to Ctrl-D w systemach Unix) na EOF, chyba że ten klawisz kontrolny został wyłączony. Aplikacja odczytuje EOF zamiast faktycznego naciśnięcia klawisza. Oznacza to, że read()zwraca zero bajtów zamiast dowolnego określonego znaku.
psusi
1
@barlop, to właśnie mówiłem: nie zwraca żadnego znaku. read () zwraca liczbę bajtów przechowywanych w buforze. W EOF po prostu daje zero bajtów. To jest sygnał, że dotarłeś do końca pliku i że nie ma już nic do czytania.
psusi
1

Zastosowane kodowanie Unicode nie jest oparte na systemie operacyjnym.

Nawet Windows notepad.exe ma wymienione opcje - (wstawię w nawiasach, co oznacza przez to notatnik) ANSI (nie Unicode), Unicode (notatnik oznacza Unicode LE), Unicode Big Endian (BE), UTF-8

ANSI nie jest Unicode, zawiera bardzo ograniczoną liczbę znaków, więc odłóżmy to na bok.

Ale patrz nawet notatnik może zrobić LE, BE lub UTF-8

Poza notatnikiem, UTF-8 może być z BOM lub bez niego.

I używam Windows z Cygwin, chociaż porty Windows mogą równie dobrze zrobić \ r \ n, nawet jeśli określisz \ n Widziałem, jak robi to sed.

Nie ma jednej reguły dotyczącej tego, jakiego kodowania Unicode używa dany system operacyjny. Gdyby tak było, nie byłby to bardzo elastyczny system operacyjny.

Aby naprawdę zobaczyć różnice, poznaj Oprogramowanie, czego używa lub oferuje Kodowanie oprogramowania.

Pobierz Cygwin i xxd i / lub edytor szesnastkowy i sprawdź, co naprawdę znajduje się w pliku. Użyj polecenia „plik”, aby pomóc zidentyfikować plik. Wtedy faktycznie widzisz, czym jest UTF 16bit LE. Co to jest UTF 16bit BE. Co to jest UTF-8 (a UTF-8 może być z BOM lub bez).

Czasami możesz powiedzieć Notatnikowi, aby zapisał jako Unicode (przez co Notatnik oznacza 16-bitowy mały endian) i tak się nie stanie. Ale wybierz czcionkę Unicode, taką jak Arial Unicode, i skopiuj niektóre znaki Unicode z Charmap, a to zrobi .. I dobrym sposobem, aby zobaczyć, co robi Notatnik lub cokolwiek innego oprogramowania, jest spojrzenie na hex pliku

C:\asdf>notepad.exe a.a

C:\asdf>file a.a
a.a; Little-endian UTF-16 Unicode text, with no line terminators

C:\asdf>type a.a
aaa慡ൡ <-- though displayed aaa followed by some boxes in my cmd window
C:\asdf>

C:\asdf>xxd a.a
0000000: fffe 6100 6100 6100 6161 610d            ..a.a.a.aaa.

C:\asdf>

^^ The portion of the byte that stores the 61 is the lower value portion which with LE is stored first.

Polecenie dd (polecenie * nix uruchamiane z cygwina w systemie Windows) może je przełączyć

C:\asdf>xxd -p a.a
fffe6100610061006161610d

C:\asdf>file a.a
a.a; Little-endian UTF-16 Unicode text, with no line terminators

C:\asdf>dd if=a.a conv=swab of=a.a2
0+1 records in
0+1 records out
12 bytes (12 B) copied, 0 seconds, Infinity B/s

C:\asdf>type a.a2
a  a a aaa
C:\asdf>xxd -p a.a2
feff00610061006161610d61

C:\asdf>file a.a2
a.a2; Big-endian UTF-16 Unicode text, with no line terminators

C:\asdf>

A sam notatnik może zapisać jako UTF-16 Big Endian lub UTF-16 Little Endian lub UTF-8

wprowadź opis zdjęcia tutaj

Jeśli jesteś osobą techniczną, a nawet zwykłym użytkownikiem notatnika, nie jesteś związany żadnym kodowaniem z powodu swojego systemu operacyjnego!

Przypuszczam, że UTF-8 ma większy sens niż UTF-16, UTF-16 użyłby 16 bitów nawet dla znaków, które powinny potrzebować tylko 8 bitów. Pamiętaj jednak, że charmap pokazuje kod UTF-16.

Sublime (edytor tekstu systemu Windows) domyślnie zapisuje Unicode jako UTF-8.

Używam Windowsa, a czasem Unicode, i używam głównie UTF-8.

A ponieważ Windows jest technicznie elastyczny, Linux jest przynajmniej tak samo elastyczny technicznie!

barlop
źródło
Czy napisałeś polecenia filei typewewnątrz wiersza polecenia Cygwin?
Vesnog
xxdi typeprzypuszczam, że brakuje poleceń w standardowej instalacji Cygwin. Poza tym chcę odtworzyć twoje wyniki.
Vesnog
1
@Vesnog typeto standardowe polecenie wbudowane w cmd.exe, xxdnajprawdopodobniej domyślnie nie jest instalowane w programie cygwin, ale po zainstalowaniu programu cygwin lub po nim, jeśli uruchomisz instalację programu cygwin, otrzymasz długą listę poleceń, które możesz zainstalować w celu użycia w programie cygwin, i po prostu wpisz xxd w polu wyszukiwania instalatora cygwin i pojawi się. xxd jest również dostępny po instalacji vim7, więc możesz go również pobrać z tego miejsca.
barlop
1
@Vesnog możesz uruchamiać polecenia cygwin w cygwin lub poza cygwin. Jeśli uruchomisz je poza cygwin, dodaj c:\cygwin\bin(jeśli tam jest podkatalog bin cygwina) na swojej ścieżce. Również dowolne wewnętrzne polecenie cmd, takie jak „type” lub „dir”, lub dowolny zewnętrzny plik exe, taki jak calc.exe (kalkulator systemu Windows), można uruchomić / uruchomić z poziomu programu cygwin. Prawie wszystko, co można uruchomić z cygwina, można uruchomić z cmd i odwrotnie. Jeśli chcesz użyć bash, użyj cygwin, a jeśli napotkasz problemy z pojedynczymi lub podwójnymi cudzysłowami, uruchom polecenia cygwin w ramach cygwin i cmd w cmd.
barlop
1
@Vesnog xxd może również napisać plik, np. echo 61|xxd -r -p>a.aNastępnie spróbuj type a.a Więc możesz faktycznie zrobić zrzut bajtów za pomocą xxd -p, zmienić kolejność lub zmodyfikować bajty, a następnie podać go do xxd -r -p i uzyskać nowy inny plik z innym kodowaniem lub różne dane na podstawie starych danych. Polecenie „file” określa kodowanie na podstawie bajtów.
barlop
-1

Linux używa UTF-8, a każdy znak ma od 1 do 6 bajtów, a nie od 1 do 4 bajtów.

U00000000 - U0000007F: 0xxxxxxx
U00000080 - U000007FF: 110xxxxx 10xxxxxx
U00000800 - U0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U00010000 - U001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U00200000 - U03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U04000000 - U7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
it_is_a_literature
źródło
Zostało to już stwierdzone w odpowiedzi złożonej w 2011 r.
Ramhound