csplit 無法辨識所提供的正規表示式

csplit 無法辨識所提供的正規表示式

我正在處理這個大檔案(數據.DAT,~900MB)其中包含幾個其他檔案。它來自 PS2 遊戲。

聲音樣本(位於.AIFF格式),正是我所追求的,構成了它的大部分大小。

上網搜尋 PS2 後.DAT我發現它們基本上依賴於開發人員,並且由於這個遊戲/工具相當晦澀並且在網上找不到太多相關信息,所以我考慮自己自動化該過程。

在十六進制編輯器上檢查文件時我遇到了一些.AIFF標頭,將區塊克隆到新的.AIFF文件,無需任何進一步的工作,它們就可以播放。

我花了一段時間從我非常有限的 bash 知識中擺脫出來,並在這裡閱讀了類似的問題,我想出了這個表達方式:

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

(我在 OSX 上使用 coreutils,因此 csplit 上有 g- 前綴)

鑑於.AIFF文件以字串“FORM”開頭,並且考慮到文件中的所有樣本基本上都彼此相鄰(由可忽略的數據量間隔開,不會在樣本上產生不需要的結束噪聲),我認為 regexp

/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

基於文字的實用程式不適合操作二進位檔案。

您可能會獲得更好的結果圖書館/aifc,Py聲音文件, 或者ffmpeg命令列應用程式。

相關內容