提取BAT中的部分文本文件

时间:2022-09-13 09:48:42

I am capturing a m3U file on a daily basis but wish to parse part of it to another file with the few channels I need.

我每天都在捕获一个m3U文件,但希望用我需要的几个频道将其中的一部分解析为另一个文件。

For example I have renamed my m3U to Test.txt file which say has the following fictional structure:

例如,我已将我的m3U重命名为Test.txt文件,该文件具有以下虚构结构:

#EXTINF:0,ABC  
#live link 1
#EXTINF:0,XYZ   
#live link 2
#EXTINF:0,UVW  
#live link 3

I would just like to capture say the line staring from "#EXTINF:0,XYZ" and say the line beneath it to end up with a Output.txt as follows:

我想捕获说“#EXTINF:0,XYZ”的线条并说出它下面的一行,最后得到一个Output.txt,如下所示:

#EXTINF:0,XYZ   
#live link 2

I know that one needs to use the For loop but I am a bit of a noob on this area.

我知道需要使用For循环,但我在这方面有点像菜鸟。

2 个解决方案

#1


0  

I would do it like this, supposing the .m3u file does not contain trailing white-spaces in the lines preceded by #EXTINF, like your sample data does:

我会这样做,假设.m3u文件在#EXTINF前面的行中不包含尾随空格,就像你的示例数据那样:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "FILE=%~1"
set "HEADER=#EXTM3U"
set "PREFIX=#EXTINF"
set "MATCH=%~2"

set "FLAG="
for /F usebackq^ delims^=^ eol^= %%L in ("%FILE%") do (
    if defined FLAG (
        echo(%%L
        set "FLAG="
    )
    for /F "delims=:" %%P in ("%%L") do (
        if "%%P"=="%HEADER%" (
            echo(%%L
        ) else if "%%P"=="%PREFIX%" (
            set "LINE=%%L"
            setlocal EnableDelayedExpansion
            if /I "!LINE:*,=!"=="!MATCH!" (
                echo(!LINE!
                endlocal
                set "FLAG=#"
            ) else endlocal
        )
    )
)

endlocal
exit /B

Call the script like this, supposing it is saved as extract-entry.bat:

像这样调用脚本,假设它保存为extract-entry.bat:

extract-entry.bat "input_file.m3u" "XYZ" > "output_file.m3u"

The script walks through the given .m3u file line by line. It returns the current line unedited and resets variable FLAG, if variable FLAG is set, which is not the case at the beginning.

该脚本逐行遍历给定的.m3u文件。如果设置了变量FLAG,它将返回未编辑的当前行并重置变量FLAG,这在开头不是这种情况。

Then it looks for #EXTINF. If found (e. g., #EXTINF:0,XYZ), the string after the comma (XYZ) is compared against the given search string. If matched, the current line is output and FLAG variable is set now in order to get the following line too.

然后它寻找#EXTINF。如果找到(例如,#EXTINF:0,XYZ),则将逗号(XYZ)之后的字符串与给定的搜索字符串进行比较。如果匹配,则输出当前行并立即设置FLAG变量以获得以下行。

The header line #EXTM3U is always output.

标题行#EXTM3U始终输出。

Toggling delayed expansion makes this script robust against all characters that have special meaning to the command interpreter without losing them.

切换延迟扩展使得此脚本对所有对命令解释器具有特殊含义的字符都具有强大的功能,而不会丢失它们。

#2


1  

Put this code into the file filter.cmd.

将此代码放入filter.cmd文件中。

@echo off
set INPUT=%1&set MATCH=%2& set MATCHED=0
for /f "delims=" %%a in (%INPUT%) do call :line "%%~a"
goto :eof
:line
set EXT=&TITLE=&
for /f "tokens=1 delims=:" %%a in ("%~1") do set EXT=%%~a
for /f "tokens=1,2,* delims=:," %%a in ("%~1") do set TITLE=%%~c
if "%EXT%" == "#EXTM3U" echo %~1
if "%EXT%" == "#EXTINF" (
  set MATCHED=0
  echo %TITLE%| findstr /l %MATCH% >nul  && set MATCHED=1
)
if %MATCHED%==1 echo %~1

Use example:

filter.cmd input_file.m3u XYZ > output_file.m3u

Here is some explanation:
Every input line is split using for /f with tokens and delims. MATCHED is set if the line begins with #EXTINF and the rest contains the string to match (second argument). if MATCHED is set, the lines are output until next #EXTINF.

以下是一些解释:每个输入行都使用for / f与令牌和delim进行拆分。如果行以#EXTINF开头且其余包含要匹配的字符串(第二个参数),则设置MATCHED。如果设置了MATCHED,则输出行直到下一个#EXTINF。

#1


0  

I would do it like this, supposing the .m3u file does not contain trailing white-spaces in the lines preceded by #EXTINF, like your sample data does:

我会这样做,假设.m3u文件在#EXTINF前面的行中不包含尾随空格,就像你的示例数据那样:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "FILE=%~1"
set "HEADER=#EXTM3U"
set "PREFIX=#EXTINF"
set "MATCH=%~2"

set "FLAG="
for /F usebackq^ delims^=^ eol^= %%L in ("%FILE%") do (
    if defined FLAG (
        echo(%%L
        set "FLAG="
    )
    for /F "delims=:" %%P in ("%%L") do (
        if "%%P"=="%HEADER%" (
            echo(%%L
        ) else if "%%P"=="%PREFIX%" (
            set "LINE=%%L"
            setlocal EnableDelayedExpansion
            if /I "!LINE:*,=!"=="!MATCH!" (
                echo(!LINE!
                endlocal
                set "FLAG=#"
            ) else endlocal
        )
    )
)

endlocal
exit /B

Call the script like this, supposing it is saved as extract-entry.bat:

像这样调用脚本,假设它保存为extract-entry.bat:

extract-entry.bat "input_file.m3u" "XYZ" > "output_file.m3u"

The script walks through the given .m3u file line by line. It returns the current line unedited and resets variable FLAG, if variable FLAG is set, which is not the case at the beginning.

该脚本逐行遍历给定的.m3u文件。如果设置了变量FLAG,它将返回未编辑的当前行并重置变量FLAG,这在开头不是这种情况。

Then it looks for #EXTINF. If found (e. g., #EXTINF:0,XYZ), the string after the comma (XYZ) is compared against the given search string. If matched, the current line is output and FLAG variable is set now in order to get the following line too.

然后它寻找#EXTINF。如果找到(例如,#EXTINF:0,XYZ),则将逗号(XYZ)之后的字符串与给定的搜索字符串进行比较。如果匹配,则输出当前行并立即设置FLAG变量以获得以下行。

The header line #EXTM3U is always output.

标题行#EXTM3U始终输出。

Toggling delayed expansion makes this script robust against all characters that have special meaning to the command interpreter without losing them.

切换延迟扩展使得此脚本对所有对命令解释器具有特殊含义的字符都具有强大的功能,而不会丢失它们。

#2


1  

Put this code into the file filter.cmd.

将此代码放入filter.cmd文件中。

@echo off
set INPUT=%1&set MATCH=%2& set MATCHED=0
for /f "delims=" %%a in (%INPUT%) do call :line "%%~a"
goto :eof
:line
set EXT=&TITLE=&
for /f "tokens=1 delims=:" %%a in ("%~1") do set EXT=%%~a
for /f "tokens=1,2,* delims=:," %%a in ("%~1") do set TITLE=%%~c
if "%EXT%" == "#EXTM3U" echo %~1
if "%EXT%" == "#EXTINF" (
  set MATCHED=0
  echo %TITLE%| findstr /l %MATCH% >nul  && set MATCHED=1
)
if %MATCHED%==1 echo %~1

Use example:

filter.cmd input_file.m3u XYZ > output_file.m3u

Here is some explanation:
Every input line is split using for /f with tokens and delims. MATCHED is set if the line begins with #EXTINF and the rest contains the string to match (second argument). if MATCHED is set, the lines are output until next #EXTINF.

以下是一些解释:每个输入行都使用for / f与令牌和delim进行拆分。如果行以#EXTINF开头且其余包含要匹配的字符串(第二个参数),则设置MATCHED。如果设置了MATCHED,则输出行直到下一个#EXTINF。