Sign in to follow this  
Followers 0
ttleser

Need help with script determining filename with the largest number at the end.

13 posts in this topic

I need to be able to scan a directory for a filename with a number at the end of it, the number needs to be the largest number.

Say the directory contains the following files:

a.exe

b.exe

patch1.txt

patch101.txt

patch102.txt

patch201.txt

I need the program to be able to scan the directory for files that start with patch and end in .txt . I then need it to determine which of the files have the greatest number at the end, in this case I need it to output patch201.txt . I've got multiple computers to scan and I need to show what patch revision level this program has. Funny enough I'm doing alot of programs on alot of computers and making a big program to find the revisions of each of the programs. Some programs are registry entries, some are filenames and some are text in files. Every one seems to be different.

Did that make sense?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I wrote this a while ago to check file versions... but I'm sure it will work with .extension as well:

MsgBox(0, '', _FileCompareVersions('patch102.txt', 'patch201.txt'))
Func _FileCompareVersions($sVersion1, $sVersion2)
    Local $sSubVers1 = $sVersion1, $sSubVers2 = $sVersion2
    For $iCC = Asc('a') To Asc('z')
        $sVersion1 = StringReplace($sVersion1, Chr($iCC), $iCC)
        $sVersion2 = StringReplace($sVersion2, Chr($iCC), $iCC)
    Next
    If ($sVersion1 = '' Or $sVersion1 = '0.0.0.0') And $sVersion2 <> '' Then _
        Return SetError(1, 0, $sSubVers2)
    If $sVersion1 <> '' And ($sVersion2 = '' Or $sVersion2 = '0.0.0.0') Then _
        Return SetError(2, 0, $sSubVers1)
    Local $aVer1[2] = ['', $sVersion1], $aVer2[2] = ['', $sVersion2]
    If StringInStr($sVersion1, '.') Then $aVer1 = StringSplit($sVersion1, '.')
    If StringInStr($sVersion2, '.') Then $aVer2 = StringSplit($sVersion2, '.')
    If (UBound($aVer1) - 1) >= (UBound($aVer2) - 1) Then
        For $iCC = 1 To UBound($aVer2) - 1
            If StringLen($aVer1[$iCC]) < StringLen($aVer2[$iCC]) Then
                Do
                    $aVer1[$iCC] &= '0'
                Until StringLen($aVer1[$iCC]) = StringLen($aVer2[$iCC])
            ElseIf StringLen($aVer2[$iCC]) < StringLen($aVer1[$iCC]) Then
                Do
                    $aVer2[$iCC] &= '0'
                Until StringLen($aVer2[$iCC]) = StringLen($aVer1[$iCC])
            EndIf
            If Int($aVer1[$iCC]) > Int($aVer2[$iCC]) Then Return $sSubVers1
            If Int($aVer2[$iCC]) > Int($aVer1[$iCC]) Then Return $sSubVers2
        Next
        Return $sSubVers1
    EndIf
    For $iCC = 1 To UBound($aVer1) - 1
        If StringLen($aVer1[$iCC]) < StringLen($aVer2[$iCC]) Then
            Do
                $aVer1[$iCC] &= '0'
            Until StringLen($aVer1[$iCC]) = StringLen($aVer2[$iCC])
        ElseIf StringLen($aVer2[$iCC]) < StringLen($aVer1[$iCC]) Then
            Do
                $aVer2[$iCC] &= '0'
            Until StringLen($aVer2[$iCC]) = StringLen($aVer1[$iCC])
        EndIf
        If Int($aVer2[$iCC]) > Int($aVer1[$iCC]) Then Return $sVersion2
        If Int($aVer1[$iCC]) > Int($aVer2[$iCC]) Then Return $sVersion1
    Next
    Return $sSubVers2
EndFunc
The recursiveness you'll need to work out for yourself.

Edit:

You could also use _FileListToArrayEx()

Store all found in an Array

Make a function using StringRegExp($hFile[N], '(\d+)\.', 1) something like that, then use _ArraySort() or _ArraySortNum() to find the sum you are looking for.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Thanks for the post Smoke, got a few questions.

1. Your first line lists the actual filenames. I don't know what the filenames are with the exception it'll start with patch and the extension will be .txt. The rest is in question and potentially different on every computer.

2. You said your script looks at the file versions, but I'd need it to look at the filenames and determine the name with the largest number at the end.

That's pretty complicated script for me. :) I'll be reading through this one for a bit.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thanks for the post Smoke, got a few questions.

1. Your first line lists the actual filenames. I don't know what the filenames are with the exception it'll start with patch and the extension will be .txt. The rest is in question and potentially different on every computer.

2. You said your script looks at the file versions, but I'd need it to look at the filenames and determine the name with the largest number at the end.

That's pretty complicated script for me. :) I'll be reading through this one for a bit.

Read my edit, I don't have time to make one for you, I'd suggest you give it a whack and see what you come up with... the 2nd option I like better anyway, simple, with the ability of finding what you need file wise. If you have issues, post the code you had written up to that point, and I'm sure someone would be happy to find it for you.

As far as the above script being complicated, that script is quite generic actually, it's mostly string functions.

Edit:

I said I made it to check file versions, but the example I gave you showed you it checking your actual file itself because it had a .extension. I said it would work for what you needed it to do.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Sorry, didn't see your edit. I read your previous post before the edit.

I'll look into that. :)

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Global $highest, $first = FileFindFirstFile('patch*.txt')

While 1
    $found = FileFindNextFile($first)
    If @error Then ExitLoop
    $ver = Number(StringReplace(StringReplace($found, 'patch', ''), '.txt', ''))
    If $ver > $highest Then
        $highest = $ver
        $file = $found
    EndIf
WEnd

MsgBox(0, 'ver = ' & $highest, 'file = ' & $file)

edit - minor change to return file name and ver

Edited by xcal

Share this post


Link to post
Share on other sites

xcal:

Most excellent. Pretty simple and it works nicely. Thanks. :)

Share this post


Link to post
Share on other sites
Global $highest, $first = FileFindFirstFile('patch*.txt')

While 1
    $found = FileFindNextFile($first)
    If @error Then ExitLoop
    $ver = Number(StringReplace(StringReplace($found, 'patch', ''), '.txt', ''))
    If $ver > $highest Then
        $highest = $ver
        $file = $found
    EndIf
WEnd

MsgBox(0, 'ver = ' & $highest, 'file = ' & $file)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Thanks guys both good ways. I ended up using Xcal's because while I'm pretty new to programming and that one I could understand a little easier. Here's my revised script, but keep in mind that it's part of a larger script/program.

Func NeverWinterNights2()
    $IP = 1
    _GUICtrlListViewDeleteAllItems($listView)
    Do
    $pingpc = Ping("192.168.100."&$IP, 250)
    If $pingpc <> 0 Then
        Local $highest, $first = FileFindFirstFile('\\192.168.100.'&$IP&'\c$\Games\Atari\Neverwinter Nights 2\patch_notes*.rtf')
        While 1
            $found = FileFindNextFile($first)
            If @error Then ExitLoop
                $ver = Number(StringReplace(StringReplace($found, 'patch_notes_v', ''), '.rtf', ''))
                    If $ver > $highest Then
                        $highest = $ver
                        $file = $found
                    EndIf
        WEnd
        $string2 = StringLeft($highest,1)
        $string3 = StringMid($highest,2,2)
        $output = $string2&"."&$string3
    Else
        $output = "Offline"
    EndIf
    GUICtrlCreateListViewItem("PC " & $IP & "|" &$output, $listView)
    
; Reset variables as they were retaining previous values.
    $ver = ""
    $highest = ""
    $IP = $IP + 1
    Until $IP = 21
EndFunc

A little info. :) I own a LAN center where you can come in and play video games. Unfortunately all games are not created equal and with 20 computers and other 30 titles, it's hard to make sure all are set to the same version/patch level of game. I'm making a program that'll scan all computers and report back the results for one particular game. Like I said previously, some versions/patch levels are stored in the registry, or a filename or in a certain file. I'm slowly going through each game and trying to find out how it stores the information, then I output this information via a GUIListView. I've got a GUICombo box that you use to select which game you want to get the information from and I've got a INI file that I store the game name in.

Sigh, it's slowly getting there. 5 games down and 25 or so to go. :D

Share this post


Link to post
Share on other sites

Thanks guys both good ways. I ended up using Xcal's because while I'm pretty new to programming and that one I could understand a little easier. Here's my revised script, but keep in mind that it's part of a larger script/program.

Func NeverWinterNights2()
    $IP = 1
    _GUICtrlListViewDeleteAllItems($listView)
    Do
    $pingpc = Ping("192.168.100."&$IP, 250)
    If $pingpc <> 0 Then
        Local $highest, $first = FileFindFirstFile('\\192.168.100.'&$IP&'\c$\Games\Atari\Neverwinter Nights 2\patch_notes*.rtf')
        While 1
            $found = FileFindNextFile($first)
            If @error Then ExitLoop
                $ver = Number(StringReplace(StringReplace($found, 'patch_notes_v', ''), '.rtf', ''))
                    If $ver > $highest Then
                        $highest = $ver
                        $file = $found
                    EndIf
        WEnd
        $string2 = StringLeft($highest,1)
        $string3 = StringMid($highest,2,2)
        $output = $string2&"."&$string3
    Else
        $output = "Offline"
    EndIf
    GUICtrlCreateListViewItem("PC " & $IP & "|" &$output, $listView)
    
; Reset variables as they were retaining previous values.
    $ver = ""
    $highest = ""
    $IP = $IP + 1
    Until $IP = 21
EndFunc

A little info. :) I own a LAN center where you can come in and play video games. Unfortunately all games are not created equal and with 20 computers and other 30 titles, it's hard to make sure all are set to the same version/patch level of game. I'm making a program that'll scan all computers and report back the results for one particular game. Like I said previously, some versions/patch levels are stored in the registry, or a filename or in a certain file. I'm slowly going through each game and trying to find out how it stores the information, then I output this information via a GUIListView. I've got a GUICombo box that you use to select which game you want to get the information from and I've got a INI file that I store the game name in.

Sigh, it's slowly getting there. 5 games down and 25 or so to go. :D

You would be able to shorten your code tremendously (100's to thousands of lines) if you learn how to use an array to do the tedious work for you. Is that what confused you on mine?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

@Smoke

Yes, but not only that. Complex lines of code, where multiple things going on on one line is confusing for me. I'm a novice at best on programming, sometimes my mind just isn't there for it. I was used to programming simple batch files to get what I needed done. I found this language and I found you guys very helpful on these forums so I thought I'd try something new. Necessity is truely the mother of invention, so when I have a need for some program to help me along here doing tedious stuff I turn to scripting it. Unfortunately more times than not I probably are trying to do something beyond my current ability, but I wouldn't learn then would I? It's hard to turn to the help file when you don't quite know what you're looking for. I tend to look in the forums for what I'm looking for, look for code and then searching the help file for those specific features/keywords and seeing if it's what I need.

So Smoke, your code seemed overwhelming to me. XCals seemed simplier. But I did try your Array suggestion on your editted post #2 and found it provided some interesting stuff. I plan on relooking over your code and try to understand it. :D I'm very sure that if I posted up all my code, you guys would laugh at me for doing something in 400 lines of code that you could do in 50. But it'll work for me now until my experience level grows.

Thanks both for the posts, got me going again. :)

Edited by ttleser

Share this post


Link to post
Share on other sites

@Smoke

Yes, but not only that. Complex lines of code, where multiple things going on on one line is confusing for me. I'm a novice at best on programming, sometimes my mind just isn't there for it. I was used to programming simple batch files to get what I needed done. I found this language and I found you guys very helpful on these forums so I thought I'd try something new. Necessity is truely the mother of invention, so when I have a need for some program to help me along here doing tedious stuff I turn to scripting it. Unfortunately more times than not I probably are trying to do something beyond my current ability, but I wouldn't learn then would I? It's hard to turn to the help file when you don't quite know what you're looking for. I tend to look in the forums for what I'm looking for, look for code and then searching the help file for those specific features/keywords and seeing if it's what I need.

So Smoke, your code seemed overwhelming to me. XCals seemed simplier. But I did try your Array suggestion on your editted post #2 and found it provided some interesting stuff. I plan on relooking over your code and try to understand it. :D I'm very sure that if I posted up all my code, you guys would laugh at me for doing something in 400 lines of code that you could do in 50. But it'll work for me now until my experience level grows.

Thanks both for the posts, got me going again. :)

I've never laughed at someone putting forth an effort.

If you need help understanding arrays, just post, Uten has posted a good example link (can't remember off the top of my head) and others (including myself) have explained them before. I was there 23 months ago myself :D. Actually, it was /dev/null that helped me understand them in a "Horse to Water" kind of way.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0