簡體   English   中英

Bash腳本從跨越多行的文本塊中提取信息

[英]Bash script to extract information from a block of text spanning multiple lines

我正在嘗試從bash腳本中使用mkvinfoMKV文件中提取跟蹤信息。 輸出是一連串的行,這些行具有重復的模式,作為各種磁道類型的各種磁道屬性的定界符。 曲目的示例是:

…
| + A track
|  + Track number: 6 (track ID for mkvmerge & mkvextract: 5)
|  + Track UID: 11555278830806058806
|  + Track type: subtitles
|  + (Unknown element: TrickTrackFlag; ID: 0xc6 size: 3)
|  + Enabled: 1
|  + Default flag: 0
|  + Forced flag: 0
|  + Lacing flag: 0
|  + MinCache: 0
|  + Timecode scale: 1
|  + Name: Spanish
|  + Language: spa
|  + Codec ID: S_TEXT/UTF8
|  + (Unknown element: TrackAttachmentLink; ID: 0x7446 size: 11)
|  + Codec decode all: 1
| + A track
|  + Track number: 7 (track ID for mkvmerge & mkvextract: 6)
…

給定磁道類型可以有多個實例,並且磁道的行數有些變化。 我需要從特定的軌道類型中提取某些軌道屬性。 例如,如果我想查找subtitles軌道類型的所有實例並提取Track numberCodec ID ,則可以通過grep傳遞結果:

mkvinfo "file.mkv" | grep "subtitles" -B 2 | grep "Track number"

這將輸出包含所有字幕軌道的軌道號的行。 我必須將這些行放入數組中並對其進行過濾以獲得第一個數字,以便可以將其與需要第一個數字的mkvpropedit一起使用。

類似地:

mkvinfo "file.mkv" | grep "subtitles" -A 10 | grep "Codec ID: " | sed 's/^.**: //'

輸出所有字幕軌道的編解碼器ID。

如果我確切知道包含subtitles的行之前/之后有多少行,則此方法很好用。 問題是,要包含的確切行數因文件而異。 所以我需要做的是輸出| + A track之間的整個行塊。 | + A track|+ OR | +開頭的| + A track和直線 | +EOF 我還需要過濾該塊以提取第一個Track numberCodec ID 我嘗試使用| grep -Eo [0-9]+ | head -1 | grep -Eo [0-9]+ | head -1 | grep -Eo [0-9]+ | head -1來提取每個音軌的第一個數字,但它僅對找到的第一個音軌起作用並退出。 如果有一種方法可以使其在一行中適用於所有軌道,那將很有幫助。 我使用sed作品作為Codec ID的第二個示例。

最重要的問題是:

如何提取特定 軌道類型的 特定屬性 (例如給出的示例),然后將它們放入一個或多個數組中以進行進一步處理?

我希望能夠滿足以下條件:

  1. 我想使用現有的bash (GNU bash,版本4.3.30(1)-發行版(x86_64-apple-darwin12.5.0))實用程序,如sedawkgrep等等。
  2. 我不想創建一個“中間文件”
  3. 我想簡單地的輸出mkvinfo到各種實用程序

我發現了很多線程,它們顯示了如何使用sed在兩個單詞之間找到一個文本塊,但是我無法使代碼適用於整行包含空格的字符串 也許有一種方法可以做到這一點,但我對sed了解還不足以使代碼適合我的情況。

請詳細說明您的代碼如何工作,以便我“學習如何釣魚”,以便下次我自己做。

當以復雜的方式處理多行時,我選擇的工具是awk

在每個匹配模式中,我們將匹配保存在變量中。 最后,當遇到表示新塊的字符串( | + A track ),或者到達流的末尾時,我們將打印出我們感興趣的變量的值(軌道號,編解碼器ID),但前提是類型是字幕。

mkvinfo ... | gawk '
    match($0, /Track number: ([0-9]+)/, m) {TN=m[1]}
    match($0, /Codec ID: (.*)$/, m)        {CI=m[1]}
    /Track type: subtitles/                {SUB=1}
    /^\| \+ A track$/ {if(SUB) print TN, CI; unset SUB}
    END               {if(SUB) print TN, CI; unset SUB}'

您需要gawk具有匹配功能才能捕獲帶括號的組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM