#arrays #string #batch-file #text #windows-10
Вопрос:
Предположим, в моем файле в разделе «%userprofile%~.txt»есть следующее содержимое:
Monitor: Generic PnP Monitor
Device: \.DISPLAY1
Adapter: Intel(R) UHD Graphics 630
(1920 x 1080 x 32 bpp) 60Hz default up, attached (-1920,0)
Monitor: Generic PnP Monitor
Device: \.DISPLAY4
Adapter: NVIDIA Quadro P2000
(1280 x 1024 x 32 bpp) 60Hz default up, attached (1920,0)
Monitor: Generic PnP Monitor
Device: \.DISPLAY8
Adapter: DisplayLink USB Device
(1920 x 1080 x 32 bpp) 60Hz default up, attached, primary (0,0)
Количество текстовых блоков может варьироваться.
То, что я хочу получить, — это первая из двух координат, появляющихся в последней строке каждого блока, поэтому, согласно примеру, результат должен быть:
-1920
1920
0
Чтобы сделать это в пакетном сценарии, я сначала анализирую файл с помощью начального цикла for, который извлекает строки, содержащие строку «по умолчанию вверх, прикреплено».
Затем для каждой полученной строки я ищу текст после последнего вхождения (
.
Из предыдущих результатов я ищу текст до первого появления ,
.
Я нашел решение, которое работает вне цикла for (см. Строки, отмеченные **
ниже), но я хочу, чтобы эти строки находились внутри цикла. Я попробовал строки, отмеченные *
ниже, но скрипт завершается, и я понятия не имею, в чем ошибка. Надеюсь, тривиальный недостающий фрагмент. Пожалуйста, примите во внимание мои низкие знания в области пакетных сценариев.
Мой сценарий:
@echo off
setlocal EnableDelayedExpansion
set Cnt=0
FOR /F "tokens=*" %%a IN ('findstr "default up, attached" "%userprofile%~.txt"') DO (
set /a Cnt =1
set result=%%a
for %%b in ("%result:(=" "%") do set "result=%%~b" <= * THESE LINES DON'T WORK!!!
for /f "tokens=1 delims=," %%c in ("%result%") do set "result=%%~c" <= * THESE LINES DON'T WORK!!!
call Set Monitors[%%Cnt%%]=!result!
)
for %%b in ("%Monitors[1]:(=" "%") do set "Monitors[1]=%%~b" <= ** THESE LINES WORK
for %%b in ("%Monitors[2]:(=" "%") do set "Monitors[2]=%%~b" <= ** THESE LINES WORK
for %%b in ("%Monitors[3]:(=" "%") do set "Monitors[3]=%%~b" <= ** THESE LINES WORK
for /f "tokens=1 delims=," %%c in ("%Monitors[1]%") do set "Monitors[1]=%%~c" <= ** THESE LINES WORK
for /f "tokens=1 delims=," %%c in ("%Monitors[2]%") do set "Monitors[2]=%%~c" <= ** THESE LINES WORK
for /f "tokens=1 delims=," %%c in ("%Monitors[3]%") do set "Monitors[3]=%%~c" <= ** THESE LINES WORK
echo %Monitors[1]%
echo %Monitors[2]%
echo %Monitors[3]%
pause
Комментарии:
1. У вас проблема с расширением переменной с первыми двумя отмеченными строками. Любая переменная, созданная или измененная внутри блока кода, заключенного в скобки, должна использовать отложенное расширение. Это означает, что вы используете восклицательные знаки с переменной вместо символов процента.
2. Независимо от этого я бы просто использовал левую и правую круглые скобки в качестве разделителей и использовал соответствующий токен, который был бы равен 3. Затем введите его через другую команду FOR /F и используйте запятую в качестве разделителя.
3. @Squashman не могли бы вы помочь мне в том, как будут выглядеть эти строки?
Ответ №1:
Альтернативой является использование регулярного выражения powershell для этого:
@Echo off
:# Replace with actual filename
Set "File=%~dp0in.txt"
Set "Content=(-?d ,d )$"
Set "Prefix=^.*?, w ("
Set "Suffix=,d*)"
:# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_regular_expressions?view=powershell-7.1
Set "[i]=1"
For /f "Delims=" %%G in ('
powershell -nologo -noprofile -c ^
"(GC "%File%") -match '%Content%' | ForEach {"$_" -replace '%Prefix%' -replace '%Suffix%'}
')Do Call Set /A "[i] =1","Monitor[%%[i]%%]=%%G"
Set Monitor[
Goto :Eof
Ответ №2:
Вы можете использовать круглые скобки и запятую в качестве разделителя, чтобы получить требуемое значение. Поскольку у вас есть дополнительные запятые в одной из строк ввода, для этого потребуются две вложенные FOR
команды. Первый FOR
разделит его на скобки и даст вам все, что находится между вторым набором скобок. Затем поместите этот вывод в другую FOR
команду, чтобы разделить значение на запятую.
@echo off
REM use the parentheses as a delimiter
FOR /F "tokens=3 delims=()" %%G IN ('findstr "default up, attached" "file.txt"') DO (
REM USE the comma as a delimiter for the final split up of the variable.
FOR /F "TOKENS=1 delims=," %%H IN ("%%~G") DO ECHO %%~H
)
Комментарии:
1. Спасибо, очень мило. Мне немного больше нравится решение регулярных выражений от @T3RR0R, так как я предполагаю, что содержание строк может измениться в будущем.