Вопрос или проблема
У меня есть много архивов rar, и некоторые из них содержат файлы с именами, которые слишком длинные для файловой системы. При попытке извлечь их с помощью unrar x
я получаю ошибку:
Не удается создать [крайне длинное имя файла].ext
Имя файла слишком длинное
Существует ли какая-либо архивная утилита, доступная для Linux, которая может автоматически укоротить извлекаемое имя файла, сохранив расширение? Если архив можно автоматически отредактировать перед извлечением, чтобы исправить эту проблему, это тоже подойдет.
С помощью bsdtar
от libarchive (который поддерживает, по крайней мере, некоторые версии rar файлов, а также десятки других форматов архивов) вы можете сделать что-то вроде:
bsdtar -'s|\([^/]\{100\}\)[^/]*|\1|gp' -xvvf file.rar
Это усечет компоненты пути к файлу до 100 символов¹. Вы можете изменить это на:
LC_ALL=C bsdtar -'s|\([^/]\{255\}\)[^/]*|\1|gp' -xvvf file.rar
Чтобы усечь до 255 байт, что является обычным ограничением длины имени файла на Linux, но будьте осторожны, это может обрезать символ посередине, если кодировка многобайтовая (как в UTF-8, которая является стандартной во многих современных локалях).
bsdtar
может извлекать, но не создавать архивы rar, однако он может создавать более unix-подобные архивы с в общем случае лучшим сжатием и может конвертировать форматы архивов. Чтобы создать файл file.tar.xz
из вашего file.rar
с компонентами пути к файлу, усеченными до 255 байт, вы можете сделать:
LC_ALL=C bsdtar -'s|\([^/]\{255\}\)[^/]*|\1|gp' -cvvf - @file.rar |
nice pixz > file.tar.xz
Здесь используется pixz
вместо xz -T0
, так как он создает индексированные архивы, что позволяет быстрее извлекать отдельные члены архива (при условии, что вы используете pixz
для этого).
Будьте осторожны, эти операции обрезают символы / байты с конца, поэтому расширение для тех компонентов пути, которые содержат точки, будет первым, что исчезнет, и нет защиты от того, чтобы файлы не имели одинаковое имя после усечения.
Если вы знаете, что все расширения длиной 3 байта или меньше, вы можете сохранить их, изменив замену на:
LC_ALL=C bsdtar -'s|\([^/.]\{251\}\)[^/.]*|\1|gp' -xvvf file.rar
То есть усечь все последовательности байтов, кроме тех, которые представляют собой /
и .
², до 251 байта вместо последовательности байтов, кроме представляющих /
, до 255 байт.
¹ Обратите внимание, что закодированные символы UTF-8 могут быть длиной до 4 байт (ранее 6), поэтому вы все равно можете получить имена файлов длиной 400 байт, если все символы в них находятся в диапазоне U+10000 .. U+10FFFF.
² POSIX гарантирует, что кодировка .
и /
является однобайтовой, неизменной для всех локалей, и что их кодировка не встречается в кодировке любого другого символа в любой локали, поэтому это должно быть безопасным действием.
Ответ или решение
Извлечение файлов из RAR-архивов с автоматическим усечением длинных имен
Ваша ситуация с извлечением RAR-архивов, содержащих файлы с длинными именами, является распространенной проблемой в мире управления данными. При попытке извлечь такие файлы с использованием команды unrar x
, вы часто сталкиваетесь с ошибкой, указывающей на то, что имя файла слишком длинное. К счастью, существует решение для автоматического усечения длинных имен при извлечении файлов из архивов, используя утилиту bsdtar
, которая входит в набор инструментов libarchive
.
Как использовать bsdtar
bsdtar
поддерживает различные форматы архивов, включая RAR, и предлагает возможность модифицировать имена файлов во время извлечения. Чтобы усечь имена файлов, вы можете воспользоваться следующей командой:
bsdtar -'s|\([^/]\{100\}\)[^/]*|\1|gp' -xvvf файл.rar
Эта команда сокращает каждую часть пути файла до 100 символов. Если же вы хотите установить максимальную длину имени файла в 255 байт, вы можете использовать следующую команду:
LC_ALL=C bsdtar -'s|\([^/]\{255\}\)[^/]*|\1|gp' -xvvf файл.rar
Внимание к кодировке
При работе с командой, которая усечет до 255 байт, важно помнить о возможных проблемах с многобайтовой кодировкой, такой как UTF-8. В некоторых случаях, при усечении файлов, могут возникать ситуации, когда символ будет разорван, что может привести к недоступности файла. Поэтому рекомендуется избегать усечения имен, если в их составе присутствуют многоязычные символы.
Создание архивов с использованием bsdtar
Если вам нужно создать новый архив из RAR-файла с усечением имен файлов, вы можете использовать такой подход:
LC_ALL=C bsdtar -'s|\([^/]\{255\}\)[^/]*|\1|gp' -cvvf - @файл.rar | nice pixz > файл.tar.xz
Эта команда создаст архив file.tar.xz
, где все длинные имена файлов будут усечены до 255 байт. Утилита pixz
обеспечивает быструю работу с архивами, что особенно важно при частом доступе к отдельным элементам.
Сохранение расширений файлов
Если вы хотите сохранить расширения файлов при усечении, можно использовать следующую команду:
LC_ALL=C bsdtar -'s|\([^/.]\{251\}\)[^/.]*|\1|gp' -xvvf файл.rar
Этот вариант позволит усечь имя файла до 251 байта, при этом гарантируя, что расширение, состоящее из 3 символов или меньше, останется неизменным.
Заключение
Используя утилиту bsdtar
, вы можете эффективно извлекать файлы из RAR-архивов, автоматизируя процесс усечения длинных имен, что позволяет избежать ошибок, связанных с файловой системой. Это решение не только улучшает управляемость ваших данных, но и делает процесс архивации более удобным и эффективным. Помните о нюансах кодировки и возможном пересечении имен, чтобы избежать конфликтов при работе с файлами.