How to sort file contents based on pattern?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

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

How to sort file contents based on pattern?

#1 Post by SIMMS7400 » 09 Apr 2019 01:38

Hi Folks -

I have a text file that looks like such:


outbox/logs/PLAN - Custom_8001.log
outbox/logs/PLAN - Custom_242.log
outbox/logs/PLAN - Custom_243.log
outbox/logs/PLAN - Custom_244.log
outbox/logs/PLAN - Custom_245.log
outbox/logs/PLAN - Custom_246.log
outbox/logs/PLAN - Custom_40.log
outbox/logs/PLAN - Custom_41.log
outbox/logs/PLAN - Custom_42.log
outbox/logs/PLAN - Custom_43.log
outbox/logs/PLAN - Custom_44.log
outbox/logs/PLAN - Custom_45.log
outbox/logs/PLAN - Custom_46.log
As you can see, the string after the "_" varies from 2 to 4 digits. I ALWAYS need to get the file names with the "highest" numerical value after the "_".

This text file is written to by an application and it writes in in descending order, and since the batch will start at the top go down, its opposite of what I need.

Here is a batch script that works if there is no variation in length of numbers after the "_" :

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

CD C:\TEMP

SET "SEARCH=outbox/logs/PLAN - Custom_"
SET "FILE=temp.txt"

SORT "%FILE%"

FOR /F "tokens=*" %%A IN ('FINDSTR /c:"%SEARCH%" %FILE%') DO (
  SET "NAME=%%~nA" & IF "!NAME!" GTR "!MAXFILE!" SET "MAXFILE=!NAME!.log"
)
But obviously rhats not dynamic and I can't always gaurentee that will always be the case so I need to force it to grab the highest. Is this easy to achieve?

Thanks!

penpen
Expert
Posts: 1675
Joined: 23 Jun 2013 06:15
Location: Germany

Re: How to sort file contents based on pattern?

#2 Post by penpen » 09 Apr 2019 05:32

SIMMS7400 wrote:
09 Apr 2019 01:38
But obviously rhats not dynamic and I can't always gaurentee that will always be the case so I need to force it to grab the highest. Is this easy to achieve?
Yes, just cut out the number in the filename using "tokens=2 delims=_." and then compare the numbers with the content of an environment variable (for example named VALUE) initiated to -1-.


penpen

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

Re: How to sort file contents based on pattern?

#3 Post by SIMMS7400 » 09 Apr 2019 06:58

Ah yes, very simple using the tokens.

Code: Select all

FOR /F "tokens=2 delims=_." %%A IN ('FINDSTR /c:"%OUTBOX_BIN%%NAME%_" %FILE%') DO (
    SET "NUM=%%~A"
    IF !NUM! GTR !MAXNUM! SET "MAXNUM=!NUM!" & SET "MAXFILE=%NAME%_!MAXNUM!.log"
)
THanks!

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

Re: How to sort file contents based on pattern?

#4 Post by dbenham » 09 Apr 2019 07:46

Sorting numerically is one of the prime reasons I wrote JSORT.BAT v4.2 - Case sensitive sort with option for numeric sort. It is another hybrid JScript/batch utility. Full documentation is available via JSORT /?

I believe you are looking for the highest numbered file, so the following options are needed:
  • /N - Treat consecutives digits numerically
  • /R - Reverse sort (descending)
  • /C 1 - Keep the first sorted (highest) line only

Code: Select all

call jsort file.txt /n /r /c 1
You can redirect the output, or use the /O option to capture the output in a file.

If you want the value in a variable, then FOR /F works well

Code: Select all

for /f "delims=" %%F in ('jsort file.txt /n /r /c 1') do set "highest=%%F"

Dave Benham

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

Re: How to sort file contents based on pattern?

#5 Post by Squashman » 09 Apr 2019 08:34

SIMMS7400 wrote:
09 Apr 2019 06:58
Ah yes, very simple using the tokens.
Yes as you have been shown and used several times on this forum.
SIMMS7400 wrote:
09 Apr 2019 06:58

Code: Select all

FOR /F "tokens=2 delims=_." %%A IN ('FINDSTR /c:"%OUTBOX_BIN%%NAME%_" %FILE%') DO (
    SET "NUM=%%~A"
    IF !NUM! GTR !MAXNUM! SET "MAXNUM=!NUM!" & SET "MAXFILE=%NAME%_!MAXNUM!.log"
)
No need to set the FOR variable to an environmental variable. Just use the FOR variable directly with your comparison instead.

Code: Select all

set "maxnum=0"
FOR /F "tokens=2 delims=_." %%A IN ('FINDSTR /c:"%OUTBOX_BIN%%NAME%_" %FILE%') DO (
    IF %%A GTR !MAXNUM! (SET "MAXNUM=%%A" & SET "MAXFILE=%NAME%_!MAXNUM!.log")
)

Post Reply