Linux узнать кодировку имени файла

Как узнать языковую кодировку имени файла в Linux?

У меня есть каталог с

10000 файлов изображений из внешнего источника.

Многие из имен файлов содержат пробелы и знаки препинания, которые не подходят для БД или для Интернета. Я также хочу добавить номер SKU в конце каждого имени файла (для целей бухгалтерского учета). Многие, если не большинство имен файлов также содержат расширенные латинские символы, которые я хочу сохранить для целей SEO (в частности, чтобы имена файлов точно представляли содержимое файла в Google Images)

Я сделал bash-скрипт, который переименовывает (копирует) все файлы до желаемого результата. Скрипт bash сохраняется в UTF-8. После запуска он пропускает около 500 файлов (не в состоянии stat файл . ).

Я запустил в каталоге convmv -f UTF-8 -t UTF-8 и обнаружил, что эти 500 имен файлов не кодируются в UTF-8 (convmv способен обнаруживать и игнорировать имена файлов, уже существующие в UTF-8)

Есть ли простой способ узнать, какую кодировку языка они используют в настоящее время?

Единственный способ, которым я смог сам разобраться, это установить для моего терминального кодирования UTF-8, а затем перебирать все возможные кодировки кандидатов с помощью convmv, пока он не отобразит преобразованное имя, которое «выглядит правильно». У меня нет возможности быть уверенным, что все эти 500 файлов используют одну и ту же кодировку, поэтому мне придется повторить этот процесс 500 раз. Я хотел бы более автоматизированный метод, чем «выглядит правильно» .

Там нет 100% точного способа на самом деле, но есть способ дать хорошее предположение.

Существует кодекс библиотеки Python, который доступен здесь: https://pypi.python.org/pypi/chardet

Посмотрите, что для текущей переменной LANG установлено:

Создайте имя файла, которое должно быть закодировано с помощью UTF-8

Измените нашу кодировку и посмотрите, что произойдет, когда мы попытаемся перечислить ее

Хорошо, теперь у нас есть имя файла, закодированное в UTF-8, и наша текущая локаль — C (стандартная кодовая страница Unix).

Итак, запустите python, импортируйте chardet и заставьте его прочитать имя файла. Я использую некоторые оболочки (например, расширение через символ *), чтобы получить мой файл. Измените «ls m *» на любой, который будет соответствовать одному из ваших файлов примеров.

Как видите, это только предположение. Насколько хорошо предположение показывает переменная «достоверность».

Источник

HowTo: Check and Change File Encoding In Linux

The Linux administrators that work with web hosting know how is it important to keep correct character encoding of the html documents.

From the following article you’ll learn how to check a file’s encoding from the command-line in Linux.

You will also find the best solution to convert text files between different charsets.

I’ll also show the most common examples of how to convert a file’s encoding between CP1251 (Windows-1251, Cyrillic), UTF-8 , ISO-8859-1 and ASCII charsets.

Cool Tip: Want see your native language in the Linux terminal? Simply change locale! Read more →

Check a File’s Encoding

Use the following command to check what encoding is used in a file:

Option Description
-b , —brief Don’t print filename (brief mode)
-i , —mime Print filetype and encoding

Check the encoding of the file in.txt :

Change a File’s Encoding

Use the following command to change the encoding of a file:

Option Description
-f , —from-code Convert a file’s encoding from charset
-t , —to-code Convert a file’s encoding to charset
-o , —output Specify output file (instead of stdout)

Change a file’s encoding from CP1251 (Windows-1251, Cyrillic) charset to UTF-8 :

Change a file’s encoding from ISO-8859-1 charset to and save it to out.txt :

Change a file’s encoding from ASCII to UTF-8 :

Change a file’s encoding from UTF-8 charset to ASCII :

Illegal input sequence at position: As UTF-8 can contain characters that can’t be encoded with ASCII, the iconv will generate the error message “illegal input sequence at position” unless you tell it to strip all non-ASCII characters using the -c option.

Option Description
-c Omit invalid characters from the output

You can lose characters: Note that if you use the iconv with the -c option, nonconvertible characters will be lost.

This concerns in particular Windows machines with Cyrillic.

You have copied some file from Windows to Linux, but when you open it in Linux, you see “Êàêèå-òî êðàêîçÿáðû” – WTF!?

Читайте также:  Как восстановить флешку без форматирования windows

Don’t panic – such strings can be easily converted from CP1251 (Windows-1251, Cyrillic) charset to UTF-8 with:

List All Charsets

List all the known charsets in your Linux system:

Option Description
-l , —list List known charsets

8 Replies to “HowTo: Check and Change File Encoding In Linux”

Thank you very much. Your reciept helped a lot!

I am running Linux Mint 18.1 with Cinnamon 3.2. I had some Czech characters in file names (e.g: Pešek.m4a). The š appeared as a ? and the filename included a warning about invalid encoding. I used convmv to convert the filenames (from iso-8859-1) to utf-8, but the š now appears as a different character (a square with 009A in it. I tried the file command you recommended, and got the answer that the charset was binary. How do I solve this? I would like to have the filenames include the correct utf-8 characters.
Thanks for your help–

Вообще-то есть 2 утилиты для определения кодировки. Первая этo file. Она хорошо определяет тип файла и юникодовские кодировки… А вот с ASCII кодировками глючит. Например все они выдаются как буд-то они iso-8859-1. Но это не так. Тут надо воспользоваться другой утилитой enca. Она в отличие от file очень хорошо работает с ASCII кодировками. Я не знаю такой утилиты, чтобы она одновременно хорошо работала и с ASCII и с юникодом… Но можно совместить их, написав свою. Это да. Кстати еnca может и перекодировать. Но я вам этого не советую. Потому что лучше всего это iconv. Он отлично работает со всеми типами кодировок и даже намного больше, с различными вариациями, включая BCD кодировки типа EBCDIC(это кодировки 70-80 годов, ещё до ДОСа…) Хотя тех систем давно нет, а файлов полно… Я не знаю ничего лучше для перекодировки чем iconv. Я думаю всё таки что file не определяет ASCII кодировки потому что не зарегистрированы соответствующие mime-types для этих кодировок… Это плохо. Потому что лучшие кодировки это ASCII.
Для этого есть много причин. И я не знаю ни одной разумной почему надо пользоваться юникодовскими кроме фразы “США так решило…” И навязывают всем их, особенно эту utf-8. Это худшее для кодирования текста что когда либо было! А главная причина чтобы не пользоваться utf-8, а пользоваться ASCII это то, что пользоваться чем-то иным никогда не имеет смысла. Даже в вебе. Хотите значки? Используйте символьные шрифты, их полно. Не вижу проблем… Почему я должен делать для корейцев, арабов или китайцев? Не хочу. Мне всегда хватало русского, в крайнем случае английского. Зачем мне ихние поганые языки и кодировки? Теперь про ASCII. KOI8-R это вычурная кодировка. Там русские буквы идут не по порядку. Нормальных только 2: это CP1251 и DOS866. В зависимости от того для чего. Если для графики, то безусловно CP1251. А если для полноценной псевдографики, то лучше DOS866 не придумали. Они не идеальны, но почти… Плохость utf-8 для русских текстов ещё и в том, что там каждая буква занимает 2 байта. Там ещё такая фишка как во всех юникодах это indian… Это то, в каком порядке идут байты, вначале младший а потом старший(как в памяти по адресам, или буквы в словах при написании) или наоборот, как разряды в числе, вначале старшие а потом младшие. А если символ 3-х, 4-х и боле байтов(до 16-ти в utf-8) то там кол-во заморочек растёт в геометрической прогрессии! Он ещё и тормозит, ибо каждый раз надо вычислять длину символа по довольно сложному алгоритму! А ведь нам ничего этого не надо! Причём заметьте, ихние англицкие буквы идут по порядку, ничего не пропущено и все помещаются в 1-м байте… Т.е. это искусственно придуманые штуки не для избранных америкосов. Их это вообще не волнует. Они разом обошли все проблемы записав свой алфавит в начало таблицы! Но кто им дал такое право? А все остальные загнали куда подальше… Особенно китайцев! Но если использовать CP1251, то она работает очень быстро, без тормозов и заморочек! Так же как и английские буквы…
а вот дальше бардак. Правда сейчас нам приходится пользоваться этим utf-8, Нет систем в которых бы системная кодировка была бы ASCII. Уже перестали делать. И все файлы системные именно в uft-8. А если ты хочешь ASCII, то тебе придётся всё время перекодировать. Раньше так не надо было делать. Надеюсь наши всё же сделают свою систему без ихних штатовких костылей…

Уважаемый Анатолий, огромнейшее Вам спасибо за упоминание enca. очень помогла она мне сегодня. Хотя пост Ваш рассистский и странный, но, видимо, сильно наболело.

Читайте также:  Как убрать прилипание окон windows 10

Источник

Файлы в Linux

Типы файлов в Linux

В Linux всё является файлами и tty терминалы не исключение.

Или аналогичную команду

crw—w—-. 1 andrei tty 136, 1 Nov 19 12:43 /dev/pts/1

Первый символ — это тип файла.

Доступно семь типов файлов: обычные, директории, символьные, блоки, сокеты, именованые каналы, символьные ссылки

— : regular file
d : directory
c : character device file
b : block device file
s : local socket file
p : named pipe
l : symbolic link

Тип c означает character. То есть этот файл может принимать и показывать символы

drwxr-xr-x. 118 root root 8192 Nov 19 11:02 /etc

Видно, что тип файла d. То есть directory

Для просмотра дисков/блоков выполните

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 8G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 7G 0 part ├─centos-root 253:0 0 6.2G 0 lvm / └─centos-swap 253:1 0 820M 0 lvm [SWAP] sr0 11:0 1 57.7M 0 rom /run/media/andrei/VBox_GAs_6.1.10

brw-rw—-. 1 root disk 8, 0 Nov 19 11:02 /dev/sda brw-rw—-. 1 root disk 8, 1 Nov 19 11:02 /dev/sda1 brw-rw—-. 1 root disk 8, 2 Nov 19 11:02 /dev/sda2

Можно убедитсья, что тип файлов b. То есть block

? означает что должен быть один любой символ.

brw-rw—-. 1 root disk 8, 1 Nov 19 11:02 /dev/sda1 brw-rw—-. 1 root disk 8, 2 Nov 19 11:02 /dev/sda2

[12] означает что должен быть либо символ 1 либо символ 2

brw-rw—-. 1 root disk 8, 1 Nov 19 11:02 /dev/sda1 brw-rw—-. 1 root disk 8, 2 Nov 19 11:02 /dev/sda2

Когда вы хотите узнать версию системы вы можете выполнить

ls -l /etc/system-release

lrwxrwxrwx. 1 root root 14 Nov 17 13:44 /etc/system-release -> centos-release

Тип файла l означает link то есть это не настоящий файл, а ссылка

ls -l /etc/system-release /etc/centos-release /etc/redhat-release

-rw-r—r—. 1 root root 37 Oct 23 17:53 /etc/centos-release lrwxrwxrwx. 1 root root 14 Nov 17 13:44 /etc/redhat-release -> centos-release lrwxrwxrwx. 1 root root 14 Nov 17 13:44 /etc/system-release -> centos-release

/etc/centos-release — это настоящий (regular) файл а остальные — ссылки на него.

Если бы вы пользовались redhat то настоящим был бы redhat-release

Ещё один способ получить информацию о версии — выполнить lsb_release -d где -d означает description

Description: CentOS Linux release 7.9.2009 (Core)

Узнать расположение файла

Узнать где находится файл lsb_release можно командой which lsb_release. Чтобы сразу получить дополнительную информацию выполните

ls -lF $(which lsb_release)

-rwxr-xr-x. 1 root root 15929 Mar 27 2015 /usr/bin/lsb_release*

Опция -F означает показать тип файлов. Поэтому нам удалось увидеть * после lsb_release. * означает, что файл исполняемый.

Чтобы узнать откуда взялся файл можно воспользоваться командой rpm с опциями q (query) и f (file)

rpm -qf $(which lsb_release)

Чтобы скопировать файл в интерактивном режиме воспользуйтесь командой cp с опцией i (interactive)

interactive означает, что если файл с таким имененм существует, вас спросят прежде чем затирать его

cp -i /etc/hosts .
cp -i /etc/hosts .

cp: overwrite ‘./hosts’?

Чтобы создать директорию сразу же с поддиректорией внутри воспользуйтесь командлой mkdir с опцией p (parent)

mkdir -p sites/heiheiru
ls -l sites

total 0
drwxrwxr-x. 2 andrei andrei 6 Nov 19 13:40 heiheiru

Создать сразу несколько файлов

Чтобы создать одновременно несколько файлов с именами идущими по порядку выполните touch с <>

touch files/file <1..5>
ls -l files

-rw-rw-r—. 1 andrei andrei 0 Nov 19 13:46 file1 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:46 file2 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:46 file3 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:46 file4 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:46 file5

Чтобы скопировать директорию files в директорию sites со всем содержимым выполните

cp -R files sites
ls -l sites/files/

total 0 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:49 file1 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:49 file2 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:49 file3 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:49 file4 -rw-rw-r—. 1 andrei andrei 0 Nov 19 13:49 file5

Директория files была скопирована в директорию sites, то есть теперь у sites есть поддиректория files.

Если у вас установлен модуль tree вы можете наглядно изучить вложенность. Если нет — выполните сперва sudo yum install tree

sites └── files ├── file1 ├── file2 ├── file3 ├── file4 └── file5 1 directory, 5 files

Создать ссылку можно командой ln, символьную ссылку ln -s

Источник

Как узнать кодировку файловой системы?

Как узнать кодовые таблицы, используемые для именования файлов
файловой подсистемой Linux и Windows, из программы на Си (gcc, MinGW32)?
Например, файловых систем Ext3, XFS, NTFS, FAT32?

В Linux у файловых систем нет кодировки, имена пишутся напрямую, без какого-либо преобразования. Считайте что кодировка имён файлов совпадает с текущей локалью.

Что ж тогда модули ядерные делают с таблицами кодировок?

>В Linux у файловых систем нет кодировки, имена пишутся напрямую, без какого-либо преобразования

Ага. Особенно когда под линуксом где-то примонтирована файловая система NTFS, в которой Unicode вшит по определению.

Читайте также:  Сжатие pdf для mac os

Преобразования делаются по-любому и при монтировании кодировки указываются. Если честно, точно не знаю где и как это делается, но думаю для каждой примонтированой fs есть отдельная настройка какое преобразовании надо осуществлять из текущей локали в кодировку fs и обратно.

Вообще-то, Eshkin_kot правильно сказал: мало ли какая ФС у вас примонтирована, все равно в опциях монтирования указывается текущая локаль. Так что париться на этот счет не надо. А уж узнать кодировку имен файлов «родной» линуксовой системы без enca невозможно: у меня, например, USB-HDD, локаль — koi8-r; если я подключу этот винт человеку с юникодом, ясное дело, вместо русских имен файлов у него будет черт те что, и узнать, какая же кодировка там на самом деле, можно только так: ls . | enca.

Признаю. Был не прав. Похоже ext2/ext3 не делает преобразований. Это делается в fat/ntfs.

> Признаю. Был не прав. Похоже ext2/ext3 не делает преобразований. Это делается в fat/ntfs.

Ещё в cifs/smbfs, iso9660, jfs, . Причём это преобразование не зависит от локали пользовательского процесса, а задаётся жёстко, одно на всех, при монтировании 🙁

На этот случай в mc есть новая очень полезная штука — преобразование кодировки в панели. При копировании тоже можно сделать преобразование. Правда, с юникодом пока не работает — приходится после копирования таких файлов переименовывать их в КОИ-8 скриптиком.

есть ещё convmv, fuse-convmvfs только это всё костыли, из-за того что в Linux у файловых систем нет кодировки. 🙁

в Linux у файловых систем нет кодировки

А зачем файловой системе кодировка? ФС наплевать, как вы обзовете файл. Этим уже ядро и пользовательские процессы занимаются. А узнать кодировку труда не составляет.

Именно. Для файловой системы имя файла — набор байт. Интерпретация этих последовательностей байтов возлагается на пользовательские программы. Можно иметь одновременно файлы в одной директории с именами во множестве кодировок.

А зачем файловой системе кодировка? ФС наплевать, как вы обзовете файл. Этим уже ядро и пользовательские процессы занимаются.

Кстати, очень ценное замечание, жаль что такое понимание приходит с опытом, а не прописывается в манах изначально.

Действительно, в опциях монтирования кодировка не указывается явно.

Хотя вот для ntfs есть опции

Но это, видимо, для решения проблемы состыковки кодировок разной битности , а не состыковки разных кодировок одинаковой битности.

И для стыковки кодировок одинаковой битности. Как по-вашему, я могу прочитать русские имена файлов/директорий на флешке в fat32 или на диске, записанном в мастдае (без рокриджа), когда у меня кодировка КОИ-8? Той же опцией iocharset=koi8-r 🙂

Вот это и странно, ведь согласно идее http://www.linux.org.ru/jump-message.jsp?msgid=4509712&cid=4511106 программе монтирования должно быть пофиг на кодировку.

Это дело файлового менеджера или другой программы, с помощью которой проводится чтение/запись.

Тогда лучше считать, что опция монтирования iocharset= излишне умничает и пытается влезть не в свой «домен». Ведь, действительно, в общем случае на ФС могут быть файлы в разных кодировках, e.g. диски со школьным линуксом 😉

А ей и так пофиг. Это просто опция, облегчающая жизнь пользователю.

>Это дело файлового менеджера или другой программы, с помощью которой проводится чтение/запись
имхо, преобразование имен файлов из кодировки, в которой они были первоначально туда записаны какой-либо не очень продвинутой осью, в локальную кодировку всей системы лежит как раз на плечах драйвера ФС.

в случае, если они совпадают — никаких действий производить не надо.
в принципе это и есть действие по умолчанию. т.е. если специально не указано драйвер считает, что кодировка на ФС совпадает с текущей кодировкой локали.
а если указать, что на фс файлы в utf8, а локаль при этом koi8-r — надо конвертить.

> в локальную кодировку всей системы

В Linux нет локальной кодировки всей системы, каждая программа может иметь свою локаль и кодировку.

в принципе это и есть действие по умолчанию. т.е. если специально не указано драйвер считает, что кодировка на ФС совпадает с текущей кодировкой локали.

вообщето нет 🙂 если почитать man mount то можно увидеть что например для iso9660: «The default is iso8859-1», для fat: «By default, codepage 437 is used.» (это кодировка на диске) + «iocharset . The default is iso8859-1» (это кодировка локали).

>iso9660: «The default is iso8859-1»,
это, можно считать, не попадает под мои слова «если специально не указано»)

В Linux нет локальной кодировки всей системы, каждая программа может иметь свою локаль и кодировку.

да, немного перепутал. имел в виду кодировку и локаль текущего приложения.

При компиляции ядра можно указать правильную кодировку для vfat и локаль системы. Так что эти умолчания работают только для дефолтных ядер.

Источник

Оцените статью