2016-06-29 2 views
-1

Я ежедневно собираю файл m3U, но хочу разобрать его часть в другом файле с несколькими нужными мне каналами.Извлечь часть текстового файла в BAT

Например, я переименовал свою M3U в файл test.txt, который говорят, имеет следующую структуру: вымышленный

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

Я просто хотел бы, чтобы захватить сказать линию уставившись от «#EXTINF: 0, XYZ»и говорят, что линия под ней, чтобы закончить с output.txt следующим образом:

#EXTINF:0,XYZ 
#live link 2 

Я знаю, что нужно использовать цикл For, но я немного нуб в этой области.

+0

Да, это может иметь белые пробелы. – GDrago

+0

Возможно ли, что часть 'XYZ' содержит белые пробелы? могут ли быть пробелы пробелов, как в ваших данных образца? – aschipfl

ответ

0

Я хотел бы сделать это так, предположим, что файл .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 

Вызовите сценарий, как это, предполагая его сохраняется как extract-entry.bat:

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

скрипт проходит по данной строке .m3u файла построчно. Он возвращает текущую строку неотредактированной и сбрасывает переменную FLAG, если установлена ​​переменная FLAG, что не так в начале.

Тогда он ищет #EXTINF. Если найдено (например, #EXTINF:0,XYZ), строка после запятой (XYZ) сравнивается с данной строкой поиска. Если согласовано, выводится текущая строка и теперь устанавливается переменная FLAG, чтобы получить следующую строку.

Линия заголовка #EXTM3U всегда выводится.

Переключая delayed expansion, этот сценарий устойчив ко всем символам, которые имеют особое значение для интерпретатора команд, не теряя их.

+0

Спасибо - Кажется, он работает нормально для одной линии. Однако я хотел бы включить эту команду в другой файл bat и извлечь более одного канала в разные файлы ... Файл bat просто заканчивается после того, как был извлечен первый канал. – GDrago

+0

Что вы подразумеваете под * более 1 канала *? вы хотите извлечь более одного раздела '#EXTINF:' или вы имеете в виду более одной строки после одного раздела '#EXTINF:'? – aschipfl

+1

Извините, что не объяснял себя хорошо ... Мне удалось преодолеть это, используя CALL перед extract-entry.bat. Я работал хорошо. Спасибо за вашу помощь! – GDrago

1

Поместите этот код в файл 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 

Используйте пример:

filter.cmd input_file.m3u XYZ > output_file.m3u 

Вот некоторые пояснения:
Каждая входная линия расщепляется используя для/ф с жетонами и delims. MATCHED устанавливается, если строка начинается с #EXTINF, а остальная часть содержит строку для соответствия (второй аргумент). Если MATCHED установлен, строки выводятся до следующего #EXTINF.

+0

1. Не достаточно эффективно разобрать каждую строку дважды 'for/F', вы можете легко их комбинировать. 2. Вы должны заменить '% 1' на'% ~ 1', то же самое для '% 2'. 3. Синтаксис 'set 'VAR = Value" 'более безопасен для специальных символов (например, что, если строка содержит' & '?). 4. Вы должны поместить '% MATCH%' между '' '' в командной строке 'findstr'. 5.Я рекомендую предоставить ключ '/ X'' findstr' для того, чтобы весь заголовок соответствовал и/или '/ C', чтобы определить литеральную строку поиска (обратите внимание, что без'/C', пробелов в строка поиска представляет собой разделители слов). – aschipfl

+0

1. Я не пытался показать пуленепробиваемое и минимальное решение, если бы я это сделал, я бы сделал это на другом языке. Целью было проиллюстрировать использование для циклов. 2-4. Нет необходимости заменять% 1 на% ~ 1, quote set =, MATCH, INPUT, потому что они поступают из командной строки, которая уже правильно цитируется. И если кто-то запускает скрипт с неупорядоченными параметрами, содержащими &, вы ничего не можете с этим поделать. – wolfrevokcats

+0

Правильное цитирование * очень важно в пакетном режиме: использование '% ~ 1' удаляет кавычки, указывая' '% ~ 1" 'в коде, обеспечивает правильное цитирование; '% 1' расшифровывается до аргумента как есть,'% ~ 1' удаляет окружающие кавычки, поэтому ''% ~ 1 "' - самый безопасный способ иметь цитированные строки (''% 1 "' может даже привести к -котированные строки, если они уже указаны в кавычках); цитаты избегают проблем с пробелами (разделителями токенов) и специальными символами, встречающимися в строках; тем не менее, ваш ответ иллюстрирует, как работает 'for/F' ... – aschipfl

Смежные вопросы