Да, но это не очень красиво. Очевидным кандидатом для этого были бы регулярные выражения, которые у вас есть только для сопоставления (а то и очень ограниченного) в пакетных файлах. Если бы вы использовали PowerShell, то это было бы
Get-Content foo.txt | ForEach-Object {
[Regex]::Match($_, 'NUM="(\d+)"').Groups[1].Value
}
Но, к сожалению, в командном файле это немного сложнее.
Однако вы можете использовать for /f
, чтобы проанализировать файл и затем проверить токены. Тем не менее, нет простого способа проанализировать токен строки по токену. И токенизация прекращается после 31 токена (если я правильно помню). В любом случае, работает следующее:
@echo off
for /f "delims=" %%f in (foo.txt) do call :parse "%%f"
goto :eof
:parse
setlocal enabledelayedexpansion
set i=0
:parseImpl
set /a i+=1
(
for /f "tokens=%i% delims= " %%l in (%1) do (
rem Jump out if no more tokens are there
if "%%l"=="" goto :eof
rem Remember the token
set T=%%l
if "!T:~0,4!"=="NUM=" (
set N=!T:~4!
rem add redirection here if needed
echo !N:"=!
)
)
) || goto :eof
rem This above will cause the loop to stop once no more tokens are there.
rem The for loop will return a non-zero exit code then.
goto parseImpl
Это не слишком красиво, но довольно просто. Поскольку при чтении файла я могу использовать каждую строку только один раз, когда делегирую работу подпрограмме, которая перебирает строку так часто, как это необходимо. Для этого используется переменная i
, которая отслеживает текущий номер токена. Затем используется другой цикл for
, который извлекает запрошенный токен из строки. Если токен начинается с NUM=
, то предполагается, что это желаемое число. Очищен и напечатан.
Если вы хотите, чтобы они были непосредственно в файле, измените соответствующую строку на
>out.txt echo !N:"=!
Код также можно найти в моем SVN .