[英]How to process a multi-line command inside of a for /f loop?
我正在嘗試開發一個腳本來統一我當前工作的腳本來解析一些視頻文件。 第一個非常簡單,只需確保所有視頻文件都在 mkv 容器上。 接下來的幾個調用mkvmerge -i
檢查文件中的字幕、標簽、附件和其他不需要的額外內容(有時使用find
完成,有時使用findstr
,用於 RegEx)。
這是mkvmerge -i
的 output 的樣子:
File 'test.mkv': container: Matroska
Track ID 0: video (AVC/H.264/MPEG-4p10)
Track ID 1: audio (Opus)
Track ID 2: subtitles (SubRip/SRT)
Attachment ID 1: type 'image/jpeg', size 30184 bytes, file name 'test.jpg'
Attachment ID 2: type 'image/jpeg', size 30184 bytes, file name 'test2.jpg'
Attachment ID 3: type 'image/jpeg', size 30184 bytes, file name 'test3.jpg'
Chapters: 9 entries
目前,我只是 pipe 它來find
或findstr
並搜索諸如“字幕”、“字節”或: [0-9]
之類的詞。
對於每個已處理的文件,我的目標是讓mkvmerge -i
每個文件只調用一次,而不是每個腳本調用一次。 這是我重新開始的一個舊項目,我之前的嘗試可以在這個問題中看到。
Following this answer , I managed to append the output of mkvmerge -i
to a variable ( %mkvmergeinfo%
) and now all I have to do is to pipe this variable a few times and have the rest of the code act accordingly. 這是它目前的樣子:
for /f "usebackq delims= eol=$" %%c in (`echo !mkvmergeinfo! ^| find /c /i "subtitles"`) do (
if [%%c]==[0] (
...
如果我改變echo !mkvmergeinfo!
對於mkvmerge -i
,代碼的 rest 可以正常工作,但是現在我正在嘗試傳遞多行命令,當我在do
之后添加echo %%c
時,它只顯示echo !mkvmergeinfo!
(我已經檢查過了,它確實包含所有行)。
我試圖解決這個問題,將括號內的整個命令替換為對 label 的調用,這將執行回聲和 pipe,但這不起作用。
除了將 output 寫入文件而是解析該文件,還有其他方法可以解決這個問題嗎?
帶有一組處理命令行的 output 的for /F
命令會導致在后台啟動另一個 Windows 命令處理器,其中包含%SystemRoot%\System32\cmd.exe /c
和附加的命令行 ZDBC11CAABDA5BDA99F777E6。 因此,在后台此命令進程沒有啟用延遲變量擴展,因為echo !mkvmergeinfo!
. 有必要運行后台cmd.exe
並將選項/V:ON
留給選項/c
和要執行的命令行。 但這是不可能的,除了運行兩個額外的cmd.exe
,第一個帶有/c
和一個以%ComSpec% /D /V:ON /C...
開頭的命令行,正如aschipfl在上面的評論中所建議的那樣。
我建議對每個*.mkv
文件運行一次mkvmerge.exe -i
並僅使用cmd.exe
的內部命令(如FOR和IF )來處理 output,而不使用find.exe
和findstr.exe
。
例子:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%G in (*.mkv) do (
echo/
echo Processing file "%%G" ...
for /F "delims=" %%H in ('mkvmerge.exe -i "%%G"') do (
echo/
echo Processing info line: %%H
for /F "tokens=1,3,4* delims=:( " %%I in ("%%H") do (
if "%%I" == "Track" (
for /F "delims=)" %%M in ("%%L") do (
if "%%K" == "video" (
echo ... Track %%J is a video track with video codec %%M
) else if "%%K" == "audio" (
echo ... Track %%J is an audio track with audio codec %%M
) else if "%%K" == "subtitles" (
echo ... Track %%J is a subtitles track with subtitles codec %%M
)
)
) else if "%%I" == "Attachment" (
echo ... Attachment %%J is %%K %%L
)
)
)
)
endlocal
如何進一步處理mkvmerge.exe -i "%%G"
每行 output 取決於您。 這只是一個演示,導致文件 test.mkv 的發布信息test.mkv
。
Processing file "test.mkv" ...
Processing info line: File 'test.mkv': container: Matroska
Processing info line: Track ID 0: video (AVC/H.264/MPEG-4p10)
... Track 0 is a video track with video codec AVC/H.264/MPEG-4p10
Processing info line: Track ID 1: audio (Opus)
... Track 1 is an audio track with audio codec Opus
Processing info line: Track ID 2: subtitles (SubRip/SRT)
... Track 2 is a subtitles track with subtitles codec SubRip/SRT
Processing info line: Attachment ID 1: type 'image/jpeg', size 30184 bytes, file name 'test.jpg'
... Attachment 1 is type 'image/jpeg', size 30184 bytes, file name 'test.jpg'
Processing info line: Attachment ID 2: type 'image/jpeg', size 30184 bytes, file name 'test2.jpg'
... Attachment 2 is type 'image/jpeg', size 30184 bytes, file name 'test2.jpg'
Processing info line: Attachment ID 3: type 'image/jpeg', size 30184 bytes, file name 'test3.jpg'
... Attachment 3 is type 'image/jpeg', size 30184 bytes, file name 'test3.jpg'
Processing info line: Chapters: 9 entries
因此,第一行和最后一行信息 output 並沒有真正處理,而在第一個 substring (令牌)是區分大小寫的Track
或Attachment
的行上有進一步的處理。
要了解使用的命令及其工作原理,請打開命令提示符window,在其中執行以下命令,並仔細閱讀每個命令顯示的所有幫助頁面。
echo /?
endlocal /?
for /?
if /?
setlocal /?
另請參閱我在 Windows 批處理文件中對與 NEQ、LSS、GTR 等等效的符號的回答,以了解為什么將兩個字符串括在"
中進行比較是有意義的,而將它們括在[
和]
中是沒有意義的,因為方括號對於 Windows 命令處理器沒有特殊意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.