NTFS fájlnév Unicode karakterek

Sziasztok.

Van 1 olyan gondom, h. internetről letöltött fájlok között vannak olyanok, amikben speciális karakterek is vannak. Valószínűleg Unicode. Nem értek amúgy az Unicode-hoz (wikit olvasgattam, az is dereng h. van UTF-16 meg UTF-8 is, de innentől magas ez már nekem). Azt tudom h. NTFS kezeli.

A gond szerintem abból ered, h. nem ugyanolyan módon van letárolva pl. ékezetes karakterek a letöltött fájloknál, mint ahogyan én pl. egy fájlkeresőben beírom billentyűzetről látszólag ugyanazt az ékezetes karaktert. Az eredmény az, hogy ilyenkor a keresés nem adja ki találatként azt a fájlt amire kerestem és tudom h. biztosan létezik. De ha a keresést olyan részletre adom meg, ami csak ascii karaktereket tartalmaz, akkor lesz (helyes) találat olyan fájlra is, aminek a nevében amúgy ott vannak a problémás karakterek is.

Jól értelmezem, h. csak a "speciális" karakterek vannak pl. UTF-ben tárolva? Vagy az egész fájlnév sztring UTF, de a basic karakterkészletet ugyanúgy 1 bájton tárolja mint az ascii, így azoknál megegyezik a végeredmény akár unicode-módon adom meg, akár ascii-s módon?

Hozzászólások

Jól értelmezem, h. csak a "speciális" karakterek vannak pl. UTF-ben tárolva? Vagy az egész fájlnév sztring UTF, de a basic karakterkészletet ugyanúgy 1 bájton tárolja mint az ascii, így azoknál megegyezik a végeredmény akár unicode-módon adom meg, akár ascii-s módon?

UTF-16 esetében minden karakter fixen 16 biten, UTF-32 esetében minden karakter fixen 32 biten van ábrázolva.

UTF-8 esetében a karakter ábrázolás változó hosszúságú, több bájtos szekvencián történik, amiből a manapság használatos szabvány szerint a 4 bájtos szekvencia a leghosszabb. (Korábban volt olyan szabvány, ami akár 6 bájtos szekvenciákat is engedélyezett.)

nem lehet, hogy ugyanugy (nagyon hasonloan) nez ki a betu, de masik codepoint?

neked aztan fura humorod van...

internetről letöltött fájlok

Valahol itt kezdődik a gubanc. Egyszer dolgoztam 2M email headerrel. Ahhoz, hogy rendesen indexelni tudjam meg kellett határozni a karakterkeszletet. A végeredmény 24 féle jól definiálható kódolás lett, amiből az utf-8 csak egy volt. Volt egyetlen olyan subject, aminek a kódolása - egyszerűen rákeresve - egyetlen weboldalon szerepelt. Az adott levél írója az onnan kimásolt megnevezést másolta a levélbe.

Szóval a zinterneten nagy a katyvasz, ezért őszinte csodálattal és tisztelettel bámulom, ha egy weboldal ennek ellenére megjelenik vagy az email mégis odaér valahova.

A kevesebb munkát igénylő megoldás lehet az iconv segítségével ellenőrizni/egységesíteni a kódkészletet.  Mondhatnám, ahol ntfs a tipikus ott nem divi az iconv, de most már  a vindózon is van linux, nem csak a turmixgépen. ;)

Elsősorban YT-DLP kapcsán jött fel a gond, ugyanis a (gyakran hülye emoji-s és "érvénytelen" karakteres) videó TITLE-t használja a lementett fájl neveként is.

Ha megadom a azt a kapcsolót, ami szimpla limitálást végez: --restrict-filenames

akkor az kigyomlál mindent, ami nem [a-zA-Z0-9], azaz pl. space-k helyett underscore (zavaró) és más non-english karaktereket is. Innentől a magyar ékezetes karakterek is eltűnnek (zavaró), illetve emoji-k és a : ; , / \ < > | -k is (ezek mondjuk pont nem fájnak).

A következő lépcsőfok az emoji-k kiszűrésére a manuális, egyesével definiálásuk lenne, ami szerintem abnormális ötlet / lehetetlenség megcsinálni hibátlanra:

 

--replace-in-metadata title "&" "_"

--replace-in-metadata title " " ""

--replace-in-metadata title "[\U00010000-\U0010ffff]" ""

--replace-in-metadata title "[\U0000002f]" "_"

egyesével definiálásuk lenne, ami szerintem abnormális ötlet / lehetetlenség megcsinálni hibátlanra:

Ilyen a popszakma. Viszont bármilyen munkához kellő mértékű türelem és alázat kell. A szobafető sem szokott megfutamodni, ha soxor kell húzogatni az ecsetet.

Az ilyesmit úgy lehet megcsinálni, hogy a nevekből készítesz egy listát, amelyre elkezded alkalmazni a már meglévő filtereket, majd a maradék kivételre elkészíted az újabbakat. Sokkal tisztább a helyzet, ha sikerül megszerezni az input komplett táblázatát. Azokat a karaktereket is illik kódolni, amelyek előfordulhatnak.

Talán ezt az erőfeszítést már megtették korábban: man iconv

Nem teccik figyelni!

Mondhatnám, ahol ntfs a tipikus ott nem divi az iconv, de most már  a vindózon is van linux, nem csak a turmixgépen. ;)

Szóval próbálkozzál: https://learn.microsoft.com/en-us/windows/wsl/install

Avagy: Converting files to UTF-8 -> Windows computers -> Method 2

Bár számomra szimpatikusabb a Method 3, mert mindig rakok fel cygwin-t. (mert a Windows 10 Enterprise N LTSC-vel néha problémáim vannak)

Biztos létezik hozzá konverter (vagy cseretáblázat). Pl. a Firefox gond nélkül megtalálja, amikor a "normál változat" begépelésével rákeresek a videó oldalán, de ha bemásolom a komment mezőbe, akkor a helyesírás-ellenőrző már valami más szónak olvassa.

:)

Normalizalni kell a stringet, valoszinuleg a Firefox ezt megteszi, amikor keresel, a textinputba viszont, azt pastezza, ami korabban a vagolapon volt. Ide a 'C' forma valo, ami dekompozitalja az osszes karaktert, majd osszerakja megfelelo formaban (Normalization Form C == Canonical Decomposition,followed by Canonical Composition):

crux:~ czo$ uconv -x any-nfc <<<Ítéletlenül | hexdump -C
00000000  c3 8d 74 c3 a9 6c 65 74  6c 65 6e c3 bc 6c 0a     |..t..letlen..l.|
0000000f
crux:~ czo$ hexdump -C<<<Ítéletlenül
00000000  49 cc 81 74 65 cc 81 6c  65 74 6c 65 6e 75 cc 88  |I..te..letlenu..|
00000010  6c 0a                                             |l.|
00000012

MacPorts alatt siman az 'icu' tartalmazza. En 7-8 eve szoptam ezzel, amikor volt az APFS atallas. A HFS filerendszer normalizalta a fileneveket letrehozaskor/atnevezeskor/masolaskor/stb, mig az APFS nem (mondvan, ma mar senki nem csinal hulye filenveket), de rogton kiderult, hogy tevedtek :D.

Ezt a -x any-nfc  paramétert hogy találtad? Manualban nincs, uconv -L kimenetében nincs. És mi a fordítottja, ami "hagyományos" ékezetes karaktert ilyen röpülő ékezetes 2-karakteressé alakít?

Amúgy fent linkelt YT-videó letöltése után játszottam egyet:

$ cp *letlen* "$( echo *letlen* | uconv -x any-nfc )"

És végre elértem céljaimat, van egy könyvtár, benne két "azonos" nevű fájllal. Juhé! Nyilván nem azonos (pont az ékezetes fájlnevek eltérő kódolása miatt), de legalább úgy néz ki. Szokás szerint visszaellenőrizni:

$ env LC_CTYPE=C ls -b

és már látszik is, hogy más a kódolás. (Sőt lehet hogy hibásan, de a konzol font mintha nem pont ugyanolyan módon mutatná pl. az é és ü betűt - az összetett formában kicsit magasabban vannak az ékezetek. Valszeg az Í-nél is, de azt szemmel nem veszem észre.)

O, arra mar nem emlekszem, hogy az any-[normalizaciosmod] az honnan jott. A masik forma, az az NFD lesz szerintem (hint: https://unicode.org/reports/tr15/), szoval -x any-nfd .

crux:~ czo$ hexdump -C <<<Ítéletlenül
00000000  c3 8d 74 c3 a9 6c 65 74  6c 65 6e c3 bc 6c 0a     |..t..letlen..l.|
0000000f
crux:~ czo$ uconv -x any-nfc <<<Ítéletlenül | hexdump -C
00000000  c3 8d 74 c3 a9 6c 65 74  6c 65 6e c3 bc 6c 0a     |..t..letlen..l.|
0000000f
crux:~ czo$ uconv -x any-nfd <<<Ítéletlenül | hexdump -C
00000000  49 cc 81 74 65 cc 81 6c  65 74 6c 65 6e 75 cc 88  |I..te..letlenu..|
00000010  6c 0a                                             |l.|
00000012
crux:~ czo$ 

Szerk: egyebkent, sajat kodjaimban, az "ekezettelintot" mindenhol ugy hasznalom, hogy normalizalas NFD-re, majd kidobni a tobb byteos szekvenciakat. 

Így van, pontosan erre értettem azt, amit a kolléga nem értett, hogy mi az, hogy buta a Windows GUI. Pont ezért, mert nem tud ilyen low level trükköket, amivel ki lehet védeni az ilyen fajta karakterkódolási gondokat.

Egyébként az egész nem lenne probléma, ha mindenki hajlandó lenne az UTF-8-ban kiegyezni, nem UTF-16, Nem UTF-32, nem UCS-2, nem kutyapöcse. Úgy értve, hogy a buzi MS se különcködik a saját „szabványával”. Akkor soha többé nem kell semmit normalizálgatni sehová.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

itt mit kellene csinalnom, hogy "szív" legyen? van ugyanilyen zsírom is :)

ez szerintem szkennelve volt es ocr-ezve. mig az ocr nem tudta az utf-8-at, addig nem csinalt ilyeneket :)

 

$ hexdump -C <<<szı
00000000  73 7a c4 b1 76 cc 81 0a                           |sz..v...|
00000008

$ uconv -x any-nfc <<<szı | hexdump -C
00000000  73 7a c4 b1 76 cc 81 0a                           |sz..v...|
00000008

 

neked aztan fura humorod van...

Mi, hol legyen sziv? Miert kellene itt szivnek lennie? Melyik resze nem vilagos a commandoknak? Ezekben az esetekben a hexdump megmutatja a standard inputjara erkezo byteokat hexadecimalis es lathato formaban, az uconv pedig nem csinal semmit, csak a standard inputjan erkezo byteokat 'normlization form c'-re hozza, amik mellesleg, mar eleve NFC modbn vannak.

de ez van tobb variacioban, nem egyesevel akartam.

de hagyd.

ezzel a 2 konverzioval sikerult kidobnom a "szív́" -bol a "v" ekezetet, igy mar csak ott maradt benne, ahol a latin2-ben is ekezetes, pl. "zsíŕ", "tíź", stb.

uconv -f utf8 -t latin2 --callback skip

uconv -f latin2 -t utf8 --callback skip

neked aztan fura humorod van...

Szerkesztve: 2024. 07. 18., cs – 15:21

(Bocs, elsiettem ezt a hsz-t.)

A file névben vagy a tartalomban vannak a speciális karakterek?

Felteszem, hogy a nevében, mert hogy a tartalomban mi van, ahhoz nincs köze az NTFS-nek.

A Windows-nak az NT vonala már több mint 30 éve Unicode alapú, ez azt jelenti, hogy az oprendszerben, a filerendszerben, a Windows API-kban minden ami string, az Unicode-ban van ábrázolva. Pontosabban az Unicode-nak a 30 évvel ezelőtti változata volt a kiindulás, tehát egy karaktert két byte-on ábrázol (UCS-2), és ebben a magyar ékezetes karakterek teljesen jól definiáltak. Tehát ha a keresőprogram jól van megírva, akkor elvileg nem kéne, hogy gondot okozzon az ékezetes karakterek kezelése.

A következő kérdés, hogy milyen file kereső programot használsz? És hogy az Unicode alapon dolgozik-e? És az milyen módszert használ a file név mint sztring illesztésére?

Ha bedobsz ide egy példa szöveget (és a fórum motor nem cseszi szét) akkor könnyebb megmondani mi a baj. (tippre az, hogy amit valamilyen betűnek vélsz, az valójában nem az, hanem egy hozzá nagyon hasonlóan kinéző, csak unicode-ban létező karakter)

Elvileg a modern Windowsoknak kezelniük kell a Unicode karaktereket, a fájlnevekben egységesen UTF-32 kódolást használnak, a Win2000 óta.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Hát ez egy ingoványos kérdés, ahogy az UCS-2 és UTF-16 közti különbség is ingoványos :D

A gond ugye a 65535-nél nagyobb Unicode kódú karakterekkel van. Ezeket az UTF-16 4 byte-on ábrázolja. Az UCS-2 -ben elvileg nem ábrázolhatók, de a surrogate pair kódok pont olyanok, hogy UCS-2 -ben amúgy nincs jelentésük. Ezért gyakorlatilag általában nem tiltott, hogy egy UCS-2 byte sorozat valójában UTF-16 legyen, és néhány karakter benne 4 egymást követő byte legyen, és az UCS-2 szinten 2 "fura" karakterként lesz értelmezve. A probléma akkor van, ha mondjuk sztring hossz műveletet akarsz számolni, az UCS-2 logikája alapján az ilyen 4 byte-os rész hossza 2 karakter, holott valójában 1 karakterről van szó.

És ilyen szinten kezeli a Windows a helyettesítő párokat és az UTF-16-ot, hogy oké, mehet, de bizonyos esetben nem kezeli őket helyesen 1 karakterként. Lényegében a probléma olyan ezekkel speciális karakterekkel, mint nagyon régen egy sima "é" betűvel: van hogy jól működik, főleg ha az adott program külön készül erre, de belefuthatsz abba is, hogy nem.

Igen, bocs, félreírtam, az UCS és az UCS-2 is lényegében egy UTF-16-os kódolás némi extrával, nem értem miért emlékeztem 32-re. A lényeg, hogy kezeli, de fix hosszúságú kódolás, amin nem standard, mert a változó hosszúságú UTF-8 a szabvány minden normális rendszeren. A gond akkor van, ha valami másik rendszer alatt készült, eltérő kódolású fájlnevet akarsz használni, pl. ami még ősibb Windowson készült 1250-es kódtáblával, vagy valami orosz kódoláson, vagy modern Unix rendszeren UTF-8-as kódoláson. Ekkor is a GUI butasága miatt korlát csak. Régen én még 10-20 éve néhány kalóz anyagnál tapasztaltam ilyet, hogy valami gányolásos kódolásúak voltak a fájlnevek, amikre vagy a Windows valamelyik komponense, vagy a Total Commander beugatott, hogy nem tudja kezelni.

Linuxon pl. shellben teljesen mindegy, hogy mi a fájlrendszernek meg a fájlnévnek a kódolása, amíg be tudod vinni hozzá a karaktereket valahogy (még ha trükközve is, meg low level bájtonként definiálva), addig eléred, át tudod nevezni. Viszont Windowson a GUI buta, csak azok a lehetőségeid vannak, amit a GUI is támogat, nem tolhatod ki a határokat.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Hosszabban: Az volt a szitu, hogy egy sokak által használt windows megosztáson volt sok-sok gibabyte adat, amiket mindenféle őskövület dos-os klipperes progik is írogattak, amik néha mindenféle régi kódolást feltételeztek. A jelnség annyi volt, hogy amikor mentettem volna a teljes adathalmazt sokszor a mentés is megállt az olvashatatlan karakterek miatt.

Mivel a windows ezeket a fájlneveket utf-16 ban tárolja, és az elcseszett nevek vegyesen voltak a nem elcseszettekkel nem volt lehetőség egyöntetűen valami kódlap konverziót csinálni.

Végül az lett, hogy csináltam egy kis progit ami egyrészt ki tudja listázni az aktuális könyvtárban a fájlneveket decimális kódokkal. Így fel lehet deríteni mik a problémás kódok.

Másrészt, ha megvannak a cserélendő karakterek azokból egy kis map -fájlt írva a progi rekurzívan végigszalad a teljes mappastruktúrán és végrehajta az átnevezéseket. (Karakter cseréket)

Az eleje kicsit sziszifuszi, amíg a problámás karaktereket összeszedtem, de utána már ment rendszeresen a dolog, a mentés előtt ez szépen rendbe rakta a fájlnevelet.

Az én esetemben ez kellett (de neked lehet egészen más)

0,224=>0,225;   visszaékezetes a -> á
0,232=>0,233;   visszaekezetes e -> é
0,160=>0,225;   á
0,181=>0,193;   Á
0,130=>0,233;   é
32,26=>0,233;   é
0,144=>0,201;   É
0,161=>0,237;   í
2,199=>0,237;   í
1,4=>0,237;     í
1,65=>0,237;    í
0,146=>0,205;   Í
0,162=>0,243;   ó
2,216=>0,243;   ó
//0,224=>0,211; Ó
0,148=>0,246;   ö
32,29=>0,246;   ö
0,153=>0,214;   Ö
0,139=>1,81;    ő
0,245=>1,81;    ő
0,138=>1,80;    Ő
0,163=>0,250;   ú
//0,233=>0,218; Ú
0,129=>0,252;   ü
0,154=>0,220;   Ü
1,97=>0,220;    Ü
0,251=>1,113;   ű
0,235=>1,112;   Ű

Használat:

Abban a könyvtárban ahol a problémás fájl van (Ha sok ilyen van, másold át valahova ideiglenesen), hozz látre egy olyan fájl is amiben a kívánt karakter is benne van, aztán futtasd:

  ntfstame show -ccp=852

 

Itt a megjelenő nevekből ki tudod olvasni, hogy mit kellene cserélni és mire.

Ezeket egy map fájlba gyűjtve végre tudod hajtani az átnevezést így:

  ntfstame fix -r -ccp=852 -map="D:\hu.txt" D:\celkonyvtar

(Furcsán tapasztalom, hogy a windows cmd.exe mai napig a 852 kódlappal jeleníti meg legjobban a neveket, de ezt tapasztaltam)

Biztos van elegánsabb, jobb megoldás, ezért nem is nagyon tolakodtam vele. De végsősoron nálam bevált. Néha még most is keletkezik olyan katyvasz amire le kell futtatni.