Get line with highest numerical string

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Get line with highest numerical string

#1 Post by SIMMS7400 » 12 Mar 2020 18:50

Hello Folks -

I have a output file that I need to parse. The output file consists of this:
outbox/logs/DIM_BPMC_PLN - Account_292.log
outbox/logs/DIM_BPMC_PLN - Account_287.log
outbox/logs/DIM_BPMC_PLN - Account_285.log
outbox/logs/DIM_BPMC_PLN - Account_284.log
outbox/logs/Account Reconciliation Manager_481.log
outbox/logs/Account_Reconciliation_Manager_481.log
outbox/logs/DIM_REGEN - Custom_2080.log
outbox/logs/DIM_REGEN - Custom_2079.log
outbox/logs/DIM_BPMC_PLN - Account_207.log
outbox/logs/DIM_BPMC_PLN - Account_206.log
Test_test_test.txt
Test test test.txt
Test1_2_3 4.txt
Testing_808.txt
Test55.txt
Test5_600.txt
Test_Test.zip
Test2.zip
Test 4.zip
Test10 11_12.zip
What I need to do is return the line in the file that start with 'outbox/logs/' that has the highest number suffixed to the name. FOr instance, the code should return the following line:
outbox/logs/DIM_REGEN - Custom_2080.log
This can be done very easily in powershell but wondering if it's easy enough in batch? Thanks!

Hackoo
Posts: 103
Joined: 15 Apr 2014 17:59

Re: Get line with highest numerical string

#2 Post by Hackoo » 12 Mar 2020 20:07

With your example that you provide, this batch script may be did the trick :idea:

Code: Select all

@echo off
Title Get line with highest numerical string
Set "InputFile=%1"
If "%~x1" NEQ ".txt" Goto :Help
Set "OutPutFile=%~dp0OutPutFile.txt"
If Exist "%OutPutFile%" Del "%OutPutFile%"
@for /f "tokens=* delims=" %%a in ('Type %InputFile% ^|find /I "outbox" ^|sort') do set "LastLine=%%a"
If defined LastLine (
	Color 0A & Mode 80,3 & echo(
	echo %LastLine%>%OutPutFile%
	echo 		%LastLine%
	Timeout /T 2 /nobreak>nul
	Start "" "%OutPutFile%" & Exit
) Else (
	Color 0C & Mode 80,3 & echo( 
	echo		Nothing to parse into this file "%InputFile%"
	Timeout /T 3 /nobreak>nul & Exit
)
::------------------------------------------------------------------
:Help
Color 0C & Mode 80,3
echo(
echo       Usage : Drag and Drop a txt file over this script:"%~nx0"  
Timeout /T 5 /nobreak>nul & Exit
::------------------------------------------------------------------

SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Re: Get line with highest numerical string

#3 Post by SIMMS7400 » 13 Mar 2020 01:49

Thank you Hackadoo.

Unfortunately, I don't think it's fail proof. if I add this line to the file:
outbox/logs/DIM_BPMC_PLN - Account_2082.log
It doesn't return it. Furthermore, if I add "7898574" to a file name, it doesn't pull that either.
outbox/logs/DIM_BPMC_PLN - Account_7898574.log

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Get line with highest numerical string

#4 Post by Aacini » 13 Mar 2020 02:00

This works:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set lastNum=0

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt') do (
   set "a=%%~Na"
   for %%b in ("!a:_=.!") do set "num=%%~Xb"
   if !num:~1! gtr !lastNum! set "lastNum=!num:~1!" & set "lastLine=%%a"
)

echo %lastLine%

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Get line with highest numerical string

#5 Post by dbenham » 13 Mar 2020 19:08

It wouldn't be hard to write a custom JScript or VBScript solution.
I went ahead and developed a JREPL.BAT solution - it is significantly faster than any pure batch solution once the input becomes "large".
I used line continuation just to make it easier to read.

Code: Select all

jrepl "^outbox/logs/.*?(\d+)\.log$"^
        "$txt=false;num=parseInt($1);if (num>max){max=num;str=$src}"^
        /jbeg "var max=0,str='',num" /jend "stdout.writeLine(str)" /jmatchq /f test.txt

Dave Benham

siberia-man
Posts: 208
Joined: 26 Dec 2013 09:28
Contact:

Re: Get line with highest numerical string

#6 Post by siberia-man » 14 Mar 2020 19:15

Also (in addition to dbeham's suggestion) the wsx tool can help you to get the required result:

Code: Select all

wsx /n /e:"m=LINE.match(/^outbox\/logs\/.*?(\d+)\.log$/)||next();n=Number(m[1]);if(n>max){max=n;str=LINE}" /begin:"str='';max=0" /end:"echo(str)" test.txt

Code: Select all

wsx /n /e:"m=LINE.match(/^outbox\/logs\/.*?(\d+)\.log$/)||next();n=Number(m[1]);if(n>max){max=n;str=LINE}" /let:str= /let:max=0 /end:"echo(str)" test.txt

SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Re: Get line with highest numerical string

#7 Post by SIMMS7400 » 22 Mar 2020 03:11

Thank you, all!!

I reallly Aacini's and Dave's solutions and I am going to leverage both. The file to scan will only be about 200 lines max, give or take a few.

Thank you again and I hope everyone is healthy!

SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Re: Get line with highest numerical string

#8 Post by SIMMS7400 » 30 Jul 2020 08:17

HI AAcini -

I just wanted to say thank you again for your solution, it's working great! I am running into once issue. There are times when there is another string between the numerical portion and the .log, which I don't want to factor into the logic.

Is there a way to ignore those instances?

Code: Select all

 outbox/logs/Planning_472.log
 outbox/logs/Planning_472.pbcs.log
 outbox/logs/Planning_473.log
 outbox/logs/Planning_474.log
 outbox/logs/Planning_475.log
 outbox/logs/Planning_476.log
 outbox/logs/Planning_477.log
 outbox/logs/Planning_481.log
 outbox/logs/Planning_482.log
 outbox/logs/Planning_483.log
 outbox/logs/Planning_484.log
 outbox/logs/Planning_485.log
 outbox/logs/Planning_486.log
 outbox/logs/Planning_487.log
 outbox/logs/Planning_488.log
 outbox/logs/Planning_501.log
And it may not always be pbcs, I need to make that dynamic where if ANY string is between the numerical portion and .log, to ignore those lines.

Thanks!

SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Re: Get line with highest numerical string

#9 Post by SIMMS7400 » 30 Jul 2020 08:42

THis works:

Code: Select all

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt ^|FINDSTR /V ".pbcs.log"')
But I need to make the "pbcs" part more generic...It could be any non-numerical string here. THis seems to work with my test, but is it best practice based on my business need?

Code: Select all

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt ^|FINDSTR /R "[0-9].log"')

Squashman
Expert
Posts: 4465
Joined: 23 Dec 2011 13:59

Re: Get line with highest numerical string

#10 Post by Squashman » 30 Jul 2020 17:07

SIMMS7400 wrote:
30 Jul 2020 08:42
But I need to make the "pbcs" part more generic...It could be any non-numerical string here. THis seems to work with my test, but is it best practice based on my business need?

Code: Select all

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt ^|FINDSTR /R "[0-9].log"')
The period means match a single character. You want a literal period match.

So if you happened to read the documentation for the FINDSTR command.

Code: Select all

Regular expression quick reference:
  .        Wildcard: any character
  *        Repeat: zero or more occurrences of previous character or class
  ^        Line position: beginning of line
  $        Line position: end of line
  [class]  Character class: any one character in set
  \x       Escape: literal use of metacharacter x
You can use the Character class and an asterisk to match more than one number. You then want to match a literal period so you have to escape the period with backslash because the period is wildcard.

Code: Select all

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt ^|FINDSTR /R "[0-9]*\.log"')

SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Re: Get line with highest numerical string

#11 Post by SIMMS7400 » 31 Jul 2020 03:13

HI Squash -

When leveraging your suggestion, it does not yield the correct results.

Squashman wrote:
30 Jul 2020 17:07
SIMMS7400 wrote:
30 Jul 2020 08:42
But I need to make the "pbcs" part more generic...It could be any non-numerical string here. THis seems to work with my test, but is it best practice based on my business need?

Code: Select all

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt ^|FINDSTR /R "[0-9].log"')
The period means match a single character. You want a literal period match.

So if you happened to read the documentation for the FINDSTR command.

Code: Select all

Regular expression quick reference:
  .        Wildcard: any character
  *        Repeat: zero or more occurrences of previous character or class
  ^        Line position: beginning of line
  $        Line position: end of line
  [class]  Character class: any one character in set
  \x       Escape: literal use of metacharacter x
You can use the Character class and an asterisk to match more than one number. You then want to match a literal period so you have to escape the period with backslash because the period is wildcard.

Code: Select all

for /F "delims=" %%a in ('findstr "outbox/logs/" test.txt ^|FINDSTR /R "[0-9]*\.log"')

Aacini
Expert
Posts: 1885
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Get line with highest numerical string

#12 Post by Aacini » 31 Jul 2020 23:17

I think this do the trick:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set lastNum=0

for /F "delims=" %%a in ('findstr "outbox/logs/.*[0-9]\.log" test.txt') do (
   set "a=%%~Na"
   for %%b in ("!a:_=.!") do set "num=%%~Xb"
   if !num:~1! gtr !lastNum! set "lastNum=!num:~1!" & set "lastLine=%%a"
)

echo %lastLine%
Antonio

SIMMS7400
Posts: 539
Joined: 07 Jan 2016 07:47

Re: Get line with highest numerical string

#13 Post by SIMMS7400 » 01 Aug 2020 03:14

HI Antonio -

That did the trick, thank you so much!!!

Post Reply