Home > other >  Batch script: extract text after/before last/first occurrence of characters and store it in array
Batch script: extract text after/before last/first occurrence of characters and store it in array

Time:09-17

Suppose I have the following content in my file under "%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)

The number of text blocks can vary.

What I want to get is the first of the two coordinates appearing on the last line of each block, so according to the example, the result should be:

-1920
1920
0

To do so in a batch script, I first analyze the file by an initial for loop, that retrieves the lines containing the string "default up, attached".

Then for each retrieved string, I search for the text after the last occurrence of (.

From the previous results, I search for the text before the first occurrence of ,.

I found a solution that works outside the for loop (see lines marked with ** below), but I want these lines to be inside the loop. I tried lines marked with * below but the script exits and I have no clue what the error is. Hopefully a trivial missing piece. Please bear with my low batch scripting knowledge.

My script:

@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

CodePudding user response:

An alternative is to make use of powershell regex to do this:

@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

CodePudding user response:

You can use the parentheses and the comma as a delimiter to get the required value. Because you have extra commas in one of your input lines this will require two nested FOR commands. The first FOR will split it up by the parentheses and will give you everything between the second set of parentheses. Then put that output into another FOR command to split the value at the comma.

@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
)
  • Related