Jump to content

Get file extension from incomplete path

Recommended Posts

Hi :)

Let's say I get a path called "E:\pics\". It has pictures inside which are numbered starting at 0. Then we get something like "E:\pics\0" or "E:\pics\1" or "E:\pics\2"... The amount of numbers, thus the path of the last picture, are known to me already. For example, there are 100 pictures, which means that the files start at 0 and end at 99

However, for some things that isn't enough, because they need the file extension. They can be pretty "random", though. Sometimes it's a JPG, sometimes it's a PNG, sometimes it's a GIF.

So, I know need some kind of function that gets me the file extension, or the complete path, from an incomplete path. The input would be "E:\pics\1" and I expect and output of "E:\pics\1.jpg" for example.

Also, there is just one file extension per number. For example, it there is "E:\pics\1.jpg", there won't be a "E:\pics\1.png" anymore.

And this will be looped as well. First I get number 0, then number 1, then number 2, and so on. So I need something that is able to be repeated in a for-loop without causing problems with the parameters.

Thanks a lot!

Share this post

Link to post
Share on other sites

You can use _FileListToArray i believe. You have the folder/dir, grab the files and then loop them in the array and use the String functions to check them. For example you have 150 files in them folder (no folder just files for example). 0 to 99 is the ones you want and the other 50 its other files like "mydoc.doc", with the String (regex is a option here) functions you can check the name before the extension and put the valid ones in another array, them you will have the path (already known) and the full file name with the extension.

Share this post

Link to post
Share on other sites

Great idea. Would also make things easier in the loop. Wouldn't that screw with my memory, though? Sometimes we're talking about several hundred strings with each up to 200 symbols. I don't have a clue, if it's that good to save like 100.000 symbols in one single variable.

Share this post

Link to post
Share on other sites

Dont think so. I work with huge files with millions of characters and i never had problem. To make sure test it and watch the memory. :)

Share this post

Link to post
Share on other sites

Can I actually re-arrange that list?

Those numbers are there for a reason, so I don't really like the function screwing around with the order...

It should be 1, 2, 3,... not 1, 10, 100, 101, [...], 2, 20, 200,...

Share this post

Link to post
Share on other sites


Do you have any control over the file naming? If so then padding the numbers with leading zeroes will get you the sort you want.

If not then you can do something like this:

#include <Array.au3>

; Simulated file list
Local $aArray[] = ["E:\Pics\1.jpg", "E:\Pics\10.jpg", "E:\Pics\3.jpg", "E:\Pics\100.jpg", "E:\Pics\2.jpg"]

; Add a column
_ArrayColInsert($aArray, 1)

; And you get this:
_ArrayDisplay($aArray, "New column", Default, 8)

; Now extract the number part, pad it and add it to the new column
For $i = 0 To UBound($aArray) - 1

    ; Extract the numeric part
    $sNumber = StringRegExpReplace($aArray[$i][0], "^(.*\\)(\d+)(\..*)$", "$2")
    ; Padd it - here we use a max of 4 characters
    $sPadded = StringFormat("%04s", $sNumber)
    ; And store it
    $aArray[$i][1] = $sPadded


; And here is the result
_ArrayDisplay($aArray, "Added padded", Default, 8)

; Now sort the array on the padded column
_ArraySort($aArray, 0, 0, 0, 1)

; Which gives this
_ArrayDisplay($aArray, "Sorted padded", Default, 8)

; Now delete the added column (and revert to 1D array)
_ArrayColDelete($aArray, 1, True)

_ArrayDisplay($aArray, "Final", Default, 8)


Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:


ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area


Share this post

Link to post
Share on other sites

Old, but seems to work perfectly. Won't affect the file names in Windows, it will only affect them "virtually" (i.e. inside your script)


Edited by Inpho

Share this post

Link to post
Share on other sites

This function _ArraySortRE, is based on Melba23's post#6 example.  It sorts an array based on the results of a regular expression which is applied to each element in a specified column or the default column 0.

#include <Array.au3>

; ---- 1D array example ----
Local $aArray[] = ["E:\Pics\1.jpg", "E:\Pics\10.jpg", "E:\Pics\ab3cd.jpg", "E:\Pics\100.jpg", "E:\Pics\2.jpg"]
_ArrayDisplay($aArray, "Original Array", Default, 32)

_ArraySortRE($aArray, 0, 0, 0, 0, "(?i)(^.*\\\D*)|(\D*\..*)$")
_ArrayDisplay($aArray, "Col0 Sort Ascending", Default, 8)

; ---- 2D array examples ----
Local $aArr2D[][] = [["E:\Pics\1qw.gif", "m21a", "q32we45rt"],["E:\Pics\10.jpg", "d2t", "as3df14f"], _
        ["E:\Pics\rt3.png", 16, "zx15cv34"],["E:\Pics\100yy.jpg", "w23x", "mn9bvf4"],["E:\Pics\2.bmp", "cc19zz", 7]]
_ArrayDisplay($aArr2D, "Original Array", Default, 32)

_ArraySortRE($aArr2D, 0, 0, 0, 0, "(?i)(^.*\\\D*)|(\D*\..*)$")
_ArrayDisplay($aArr2D, "Col0 Sort Ascending", Default, 8)

_ArraySortRE($aArr2D, 0, 0, 0, 1, "\D*")
_ArrayDisplay($aArr2D, "Col1 Sort Ascending", Default, 8)

_ArraySortRE($aArr2D, 0, 0, 0, 2, "^\D*|(\D+\d*\D*)?$")
_ArrayDisplay($aArr2D, "Col2 1st number Sort Ascending", Default, 8)

_ArraySortRE($aArr2D, 0, 0, 0, 2, "(^\D+\d*\D*)?|\D*$")
_ArrayDisplay($aArr2D, "Col2 2nd number Sort Ascending", Default, 8)

;$aArray -  A 1D or 2D array to be sorted numerically on a Regular Expression derived number.
;$iDescending [optional] If set to 1, sort in descending order
;$iStart [optional] Index of array to start sorting (default 0 = first element or row)
;$iEnd [optional] Index of array to stop sorting (default 0 = last element or row)
;$iSubItem [optional] Sub-index to sort on in 2D arrays (default 0 = first column)
;RE pattern [optional] - To be applied to all elements in the $iSubItem column; and,
;                      - Is to delete all characters that are not the required sort value. This will leave only the number to be sorted; and,
;                      - When default (""), _ArraySortRE sorts the same as the _ArraySort function sorts.
;Requires - #include <Array.au3>
Func _ArraySortRE(ByRef $aArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0, $REPattern = "")
    Local $MaxLen = 0
    _ArrayColInsert($aArray, 0); Add a new column

    ; Now extract the number part, pad it with leading zeros and add it to the new column (Col0)
    For $i = 0 To UBound($aArray) - 1
        If $REPattern = "" Then
            $aArray[$i][0] = $aArray[$i][$iSubItem + 1]
            $sNumber = StringRegExpReplace($aArray[$i][$iSubItem + 1], $REPattern, "") ; Extract the numeric part
            $aArray[$i][0] = StringRight("0000000000" & $sNumber, 10) ; Padd it with leading zeros - here we use a max of 10 characters
    _ArraySort($aArray, $iDescending, $iStart, $iEnd, 0); Now sort the array on the padded column (Col0)
    _ArrayColDelete($aArray, 0, True); Now delete the added column.
EndFunc   ;==>_ArraySortRE


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

  • Similar Content

    • By dinotom
      Can files be read from the web or the cloud?
      I am trying to read this file but get the file open error.
      #include <FileConstants.au3> #include <MsgBoxConstants.au3> ;Assign the file path to a variable Local $sFilePath = "C:\Automation\test.txt" Local $sFilePathAzure ="https://batlgroupimages.blob.core.windows.net/files/test.txt" Local $nLineNumberToLookFor = 0 ;Open the file test.txt in append mode. ;If the folder C:\Automation does not exist, it will be created. Local $hFileOpen = FileOpen($sFilePathAzure, $FO_APPEND + $FO_CREATEPATH) ;Display a message box in case of any errors. If $hFileOpen = -1 Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred while opening the file.") EndIf ;Set the file position to beginning for reading the data from the beginning of the file. FileSetPos($hFileOpen, 0, $FILE_BEGIN) ;Read the data from the file using the handle returned by FileOpen ;Local $sFileRead = FileRead($hFileOpen) ;Read the 2nd line of data from the file using the handle returned by FileOpen Local $sFileReadLine = FileReadLine ($hFileOpen,2) ;Close the handle returned by FileOpen. FileClose($hFileOpen)  
    • By Pike
      Hey Everyone, I haven't been here in a while and recently picked up my old project. Still an FNG!
      To the point: I want to be able to push the button and either play an mp3, open a file, or open an exe program (all with the same button). The problem is that I don't know how to code for that at "case 1"
              Case 1                                                                                                                                             
                  Local $sRead = IniRead("config.ini", "Config", "One", "Default")                                
                  SoundPlay($sRead, @HotKeyPressed)                                                                     <-------------------------------
                  Run($sRead, @HotKeyPressed)                                                                                 <------------------------------- This 'Run' doesn't work even by itself!
      See code below for layout. If you need more information I will attach more code or answer any questions. Any help is greatly appreciated.
      Much Respect,
      Func _HandleButton() $iClickCount += 1 $iTimer = TimerInit() AdlibRegister("CheckButtonPress", $CheckTime) EndFunc Func CheckButtonPress() If TimerDiff($iTimer) < $CheckTime Or $iTimer = 0 Then Return Switch $iClickCount Case 1 Local $sRead = IniRead("config.ini", "Config", "One", "Default") SoundPlay($sRead, @HotKeyPressed) Run($sRead, @HotKeyPressed) Case 2 MsgBox(0, "INFORMATION:", "Choose the file you want designated to this button") Local $sFileOpenDialog = FileOpenDialog(0, @ScriptDir & "\", "All (*.*)", $FD_FILEMUSTEXIST + $FD_MULTISELECT) If @error Then MsgBox($MB_SYSTEMMODAL, "", "No file(s) were selected.") EndIf Local $sFileName = InputBox("INFORMATION:", "Please Name Your File?" & @CRLF _ & @CRLF _ & "6 Characters or Less", "") IniWrite(@ScriptDir & "\config.ini", "Config", "One", $sFileOpenDialog) IniWrite(@ScriptDir & "\config.ini", "Config", "NameOne", $sFileName) EndSwitch $iClickCount = 0 AdlibUnRegister() EndFunc  

    • By nacerbaaziz
      hi dears, i have a question please
      am now working for an audio player for the blind users
      and i added an option to open a file from the right click context menu.
      but here there is a small problem, i hope that you can help me to find a solution for it.
      the problem is as follow :
      when i added the problem into the context menu it work with successfuly if the user select just one file.
      but if the user selected more then one file, here the problem
      a multiple sections of the program will open.
      my question is :
      how i can detect the multiple selection from the context menu?
      i know that it so  hard, but i know also that you are harder than it
      for that dears please try to give me an solution for that problem.
      thanks in advance
    • By VADemon
      I've encountered a problem with a single file where I cannot retrieve it's Date-time. So far my code has worked well for over 30 files, but this one is a mystery I cannot debug myself due to insufficient Au3 knowledge.
      In line 11 "_Date_Time_FileTimeToArray" is called and for this particular file it sets the @error to 10. I don't know what that error code means, but it's not set by the _Date functions themselves I think.
      Overall, it could be a problem caused by any of the functions below, how can I properly debug this? / Does anybody know a what's causing this?
      _WinAPI_CreateFile() / _Date_Time_GetFileTime() / _Date_Time_FileTimeToArray()
      Func _SetFileTimes($sFilePath) Local $monthNumber[13] = ["", "January", "February", "March", "April", "May", "Juny", "July", "August", "September", "October", "November", "December"] Local $dayNumber[7] = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] Local $fHandle = _WinAPI_CreateFile($sFilePath, 2, 2) ; read-only ; may NOT return a valid date for some reason! TODO Local $fTagFILETIME = _Date_Time_GetFileTime($fHandle) _WinAPI_CloseHandle($fHandle) ; This will return an empty array if theres no valid date $fModTime = _Date_Time_FileTimeToArray($fTagFILETIME[2]) ; last Modified if @error <> 10 then Local $year = $fModTime[2] Local $month = $fModTime[0] Local $day = $fModTime[1] Local $hour = $fModTime[3] Local $min = $fModTime[4] Local $sec = $fModTime[5] Local $ms = $fModTime[6] Local $weekday = $fModTime[7] Global $prettyTimestamp = StringFormat("%s, %s %d, %04d %02d:%02d:%02d", $dayNumber[$weekday], $monthNumber[$month], $day, $year, $hour, $min, $sec) Global $uploadDate = StringFormat("%04d-%02d-%02d", $year, $month, $day) $fModTime = _Date_Time_FileTimeToArray(_Date_Time_FileTimeToLocalFileTime($fTagFILETIME[2])) ; last Modified Local $year = $fModTime[2] Local $month = $fModTime[0] Local $day = $fModTime[1] Local $hour = $fModTime[3] Local $min = $fModTime[4] Local $sec = $fModTime[5] Local $ms = $fModTime[6] Local $weekday = $fModTime[7] ; GetUnixTime accounts for Local time, hence feed it local time Global $unixTimestamp = _GetUnixTime($year &"/"& $month &"/"& $day &" "& $hour&":"& $min &":"& $sec) else Global $prettyTimestamp = "N/A" Global $uploadDate = "" Global $unixTimestamp = "N/A" endif endfunc  
      _GetUnixTime returned the year 1601 start date, showing that $fModTime is probably equal 0. (But Why?)
      The file reports these dates in Explorer, it's on local NTFS drive:
      Created: ‎‎Wednesday, ‎31. ‎Januar ‎2018, ‏‎18:55:02
      Modified: ‎Wednesday, ‎10. ‎Januar ‎2018, ‏‎12:39:23
      Accessed: ‎Wednesday, ‎10. ‎Januar ‎2018, ‏‎12:39:23
    • By TheSaint
      Files Checklist
      Just a simple little (complex enough) program I whipped up, for a purpose ... but only too happy to share.
      It can of course be modified to do more, but at the moment just compares file names with or without path ... Location versus Checklist.
      There are of course other compare programs out there, most doing a lot more than mine (i.e. WinMerge or FileComparer). But I wanted something quick and simple with drag & drop, that uses up a smallish amount of screen real estate.
      NOTE - The SAVE button is also a LOAD one, and displays 'Load' when the list is empty. So you can save and load specific lists. While in SAVE mode, the button can also be used with CTRL held down, to ADD another list to existing (displayed one) ... combining as they say ... though not saved until you SAVE. CLEAR button removes a selected entry, or if used with CTRL held down, queries about removing all listed entries.
      Files Checklist v1.2.zip
      Files Checklist v1.3.zip
      Files Checklist v1.4.zip  (Includes a BUGFIX.)
        (source included)
      WARNING - While this program does not act on files or folders ADDED or CHECKED, you might act on the results, so I advise caution, and I also recommend using the new 'Relative' option in v1.3 or newer ... but you still need to understand what you are doing and what the results actually mean. Some basic examples in the next post.
      Users might also be interested in another somewhat related program of mine.
      DeleteIf Same
  • Create New...