csplit не распознает предоставленное регулярное выражение

csplit не распознает предоставленное регулярное выражение

Я работаю над этим большим файлом (ДАННЫЕ.DAT, ~900 МБ), который содержит несколько других файлов. Это из игры PS2.

Звуковые образцы (которые находятся в.AIFFформат), именно то, что мне нужно, составляют большую часть его размера.

После поиска в Интернете PS2.ДАТэкстракторы Я обнаружил, что они в основном зависят от разработчика, и поскольку эта игра/инструмент довольно малоизвестны и в Интернете о них мало что можно найти, я подумал о том, чтобы автоматизировать этот процесс самостоятельно.

Проверяя файл в шестнадцатеричном редакторе, я наткнулся на некоторые.AIFFзаголовки, клонировал куски на новые.AIFFфайлы и без какой-либо дальнейшей работы их можно было воспроизвести.

Потратив некоторое время на то, чтобы избавиться от ржавчины в моих ОЧЕНЬ ограниченных знаниях bash и прочитав похожие вопросы здесь, я придумал следующее выражение:

gcsplit -f "sample-" -b "%04d.aif" DATA.DAT /FORM/ '{*}'

(Я работаю на OSX, использую coreutils, отсюда и префикс g- в csplit)

При условии.AIFFфайлы начинаются со строки «FORM» и, учитывая, что в основном все образцы в файле находятся рядом друг с другом (разделенные незначительным количеством данных, которое не будет создавать нежелательный конечный шум в образцах), я подумал, что регулярное выражение

/FORM/

было бы достаточно разделить файлы.

Однако каждый разделенный файл выводится с мусорными данными, которые находятся между звуковыми сэмплами перед.AIFFзаголовок, что делает его невоспроизводимым.

Скриншоты шестнадцатеричных данных разделенного звукового образца ниже:

плохой раскол

Этот фактический пример начинается примерно с отметки 1500 байт:

образец

Что заставляет это выражение разделять файлы со смещением?

решение1

Csplit — это текстовая утилита. Она основана на строках. Шаблон /FORM/означает «строка, содержащая FORM». Строка — это последовательность байтов, отличных от LF (перевод строки, также известный как новая строка, который может быть записан \n, ^J, …), за которой следует байт LF (или конец файла с помощью утилит GNU). Таким образом, «мусор», который вы видите, — это то, что находится между предыдущим символом LF и FORMподстрокой.

Страница руководства и --helpкраткое описание предполагают, что вы уже знаете, что делает команда, поэтому они просто упоминают «части» без объяснений. Вам нужно прочитатьполная документациячтобы получить описание того, что представляют собой эти части.

Вы не можете делать то, что хотите, с csplit. Вы можете сделать это с GNU awk. (Другие версии awk могут не иметь необходимых функций — поддержки произвольных разделителей записей и обработки нулевых байтов.) Непроверено:

gawk -v RS='FORM' -v ORS='' '{
    print "FORM" $0 >sprintf("sample-%04d.aif", n++)
}' DATA.DAT

Но это может привести к сбою в ложных местах, если сжатые данные просто содержат четыре байта FORM. Этого может быть достаточно для одноразовой операции с ручным просмотром, но вам лучше использовать инструмент с поддержкой формата, если вам нужно что-то надежное.

решение2

Текстовая утилита не подходит для работы с двоичными файлами.

Вы, вероятно, получите лучшие результаты сLib/aifc,PySoundFile, илиffmpegприложение командной строки.

Связанный контент