![](/img/trans.png)
[英]Extract multiple lines from large text file with sed while preserving each trailing newline (Bash Script)
[英]Bash script to extract information from a block of text spanning multiple lines
我正在嘗試從bash
腳本中使用mkvinfo
從MKV
文件中提取跟蹤信息。 輸出是一連串的行,這些行具有重復的模式,作為各種磁道類型的各種磁道屬性的定界符。 曲目的示例是:
…
| + 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 number
和Codec 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 number
和Codec ID
。 我嘗試使用| grep -Eo [0-9]+ | head -1
| grep -Eo [0-9]+ | head -1
| grep -Eo [0-9]+ | head -1
來提取每個音軌的第一個數字,但它僅對找到的第一個音軌起作用並退出。 如果有一種方法可以使其在一行中適用於所有軌道,那將很有幫助。 我使用sed
作品作為Codec ID
的第二個示例。
最重要的問題是:
如何提取特定 軌道類型的 特定屬性 (例如給出的示例),然后將它們放入一個或多個數組中以進行進一步處理?
我希望能夠滿足以下條件:
bash
(GNU bash,版本4.3.30(1)-發行版(x86_64-apple-darwin12.5.0))實用程序,如sed
, awk
, grep
等等。 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.