web-dev-qa-db-ja.com

csplitが提供された正規表現を認識しない

私は他のいくつかのファイルを含むこの大きなファイル(DATA.DAT、〜900MB)に取り組んでいます。 PS2ゲームからです。

サウンドサンプル(。AIFF形式)は、まさに私が求めているものであり、そのサイズの大部分を占めています。

WebでPS2。DATエクストラクターを検索したところ、基本的に開発者に依存していることがわかりました。このゲーム/ツールはかなりあいまいで、オンラインではあまり見つけられないため、プロセスを自分で自動化することについて。

16進エディターでファイルを調べると、いくつかの。AIFFヘッダーに出くわし、チャンクを新しい。AIFFファイルに複製しました。さらなる作業、彼らはプレイ可能でした。

非常に限られたbashの知識からRustを取得し、ここで同様の質問を読んだ後、次の式を思いつきました。

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

(私はcoreutilsを使用しているOSXを使用しているため、csplitのg-プレフィックス)

。AIFFファイルが文字列 "FORM"で始まり、基本的にファイル内のすべてのサンプルが互いに隣接していることを前提としています(無視できない量のデータによって間隔が空けられています。サンプルに不要なエンドノイズが発生する)、正規表現だと思いました

/FORM/

ファイルを分割するのに十分でしょう。

ただし、すべての分割ファイルは、。AIFFヘッダーの前のサウンドサンプルの間にあるジャンクデータで出力されているため、再生できません。

以下のスプリットサウンドサンプルの16進データのスクリーンショット:

bad split

この実際のサンプルは、およそ1500バイトのマークから始まります。

sample

この式でファイルがオフセットで分割されるのはなぜですか?

5
João

Csplitはテキストユーティリティです。ラインベースです。パターン/FORM/は、「FORMを含む行」を意味します。行は、LF(改行、改行とも呼ばれ、\n、^ J、…と書くことができます)以外のバイトのシーケンスであり、その後にLFが続きます。 _バイト(またはファイルの終わりまでに、GNUユーティリティを使用)。したがって、観察される「ジャンク」は、前のLF文字とFORM部分文字列の間にあるものです。

マニュアルページと--helpの簡単な説明は、コマンドの機能をすでに知っていることを前提としているため、説明なしで「ピース」について言及しているだけです。ピースが何であるかの説明を取得するには、 完全なドキュメント を読む必要があります。

Csplitではやりたいことができません。 GNUawkでそれを行うことができます。 (awkの他のバージョンには、必要な機能がない場合があります—任意のレコードセパレーターのサポートとnullバイトへの対処。)未テスト:

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

しかし、圧縮されたデータにたまたま4バイトのFORMが含まれている場合、これは誤った場所でカットされる可能性があります。これは、手動で確認する1回限りの操作には十分かもしれませんが、信頼できるものが必要な場合は、フォーマット対応ツールを使用することをお勧めします。

テキストベースのユーティリティは、バイナリファイルの操作には適していません。

Lib/aifcPySoundFile 、または ffmpeg コマンドラインアプリを使用すると、より良い結果が得られる可能性があります。

0
J_H