Jump to content

Select only the directories that contain .fit files


RaySS
 Share

Recommended Posts

In a high-level directory, some subdirectories contain files with the .fit file extension. I want to capture the names of only those subdirectories which contain .fit files. Here's a representative fragment of my code:

#include <MsgBoxConstants.au3>
#include <File.au3>
#include <WinAPIFiles.au3>
#include <Array.au3>

Global $bReturnPath = True, $aDateTime[100], $aFiles[100], $aConCat[100]
Local $sFilePth = "E:\Clif\Doublestar\", $iHits
$aList = _FileListToArray($sFilePth, Default, $FLTA_FOLDERS)

If IsArray($aList) Then
    For $a = 1 To $aList[0]

        ConsoleWrite("File name is " & $aList[$a] & * .fit & @CRLF) ;this should be a fully qualified file name.

        If (Not FileFindFirstFile($sFilePth & $aList[$a] & "*.fit" = -1)) Then
            ConsoleWrite("good hit" & @CRLF)
        Else
            ConsoleWrite("skip this file" & @CRLF)
        EndIf
    Next
EndIf

Here are the error messages:

"D:\Personal\Dad\AutoIT_Scripts\BoolTest.au3"(13,47) : error: syntax error
        ConsoleWrite("File name is " & $aList[$a] & *
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"D:\Personal\Dad\AutoIT_Scripts\BoolTest.au3"(13,54) : error: Object method or attribute accessed without 'With'.
        ConsoleWrite("File name is " & $aList[$a] & * .fit &
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Personal\Dad\AutoIT_Scripts\BoolTest.au3 - 2 error(s), 0 warning(s)

I'm trying to concatenate the path E:\Clif\Doublestar\ with any file in the subdirectory that has the .fit extension *.fit

A side issue: Some of the subdirectories contain up to 10.000 files. I want to stop examining files in each subdirectory as soon as I encounter the first .fit file.

Thank you for your help.

RaySS

Link to comment
Share on other sites

  • Moderators

RaySS,

This looks to work:

#include <File.au3>

Local $sFilePath = "RootPath\"

; List folders within the root folder
$aList = _FileListToArray($sFilePath, Default, $FLTA_FOLDERS)
If IsArray($aList) Then
    For $a = 1 To $aList[0]
        ConsoleWrite("File pattern: " & $aList[$a] & "\*.fit" & @CRLF)
        ; List the files matching the wildcard in each folder
        $aFiles = _FileListToArray($aList[$a], "*.fit", $FLTA_FILES)
        If IsArray($aFiles) Then
            ConsoleWrite("Good hit" & @CRLF)
            ; Take the first such file
            $sFirstFileFound = $aList[$a] & "\" & $aFiles[1]

            ; And display it
            ConsoleWrite("File found: " & $sFirstFileFound & @CRLF)
        Else

            ; No files matching the wildcard
            ConsoleWrite("Skip this folder" & @CRLF)
        EndIf

    Next
EndIf

It does not stop at the first file - to do that would require you to modify the  _FileListToArray function internally - but it seemed pretty fast for me when I tested it.

M23

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:

Spoiler

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

 

Link to comment
Share on other sites

This should work to check the first file found

#include <File.au3>

Local $sFilePath = "E:\Clif\Doublestar\"

$aList = _FileListToArray($sFilePath, Default, $FLTA_FOLDERS, true)
If IsArray($aList) Then
    For $a = 1 To $aList[0]
        $hSearch = FileFindFirstFile($aList[$a] & "\" & "*.fit")
        While 1
             $sFileName = FileFindNextFile($hSearch)
             If @error Then ExitLoop
             ConsoleWrite($aList[$a] & "\" & $sFileName & @CRLF)
             ExitLoop
        Wend
        FileClose($hSearch)
    Next
EndIf

 

Link to comment
Share on other sites

_FileListToArrayRec() should make easy work of this.

Here is my shot at it, not sure if faster/better than other solutions already posted, but its easy to understand and use.

#Include <File.au3>
#Include <Array.au3>

Local $sRoot = "C:"
Local $sFilter = "*.fit"

;All Files Recurse To Array
$aFiles = _FileListToArrayRec($sRoot, $sFilter, $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)

;Re-Write Array Without File Results Only Directories
For $i = 1 to $aFiles[0]
    $aFiles[$i] = StringRegExpReplace($aFiles[$i], "((.+\\).+)", "$2")
Next

;Remove Duplicate Directories Leaving Final Results
$aFinal = _ArrayUnique($aFiles, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT)
$aFinal[0] = UBound($aFinal) -1

_ArrayDisplay($aFinal)

Probably should add a _IsArray() in there for good measure as well to prevent errors if no files exist. 

This does not meet the "stop on first result" but it does do multi level recursive so if its 10 directories deep it will find it.

If its too slow in this form I would modify the _FileListToArrayRec() to show only folders not files and have a all folders filter "*", this will give you every directory listing in a single array with multi level recursive.  Then take that arrays results and do a loop with FileFindFirstFile() check using the *.fit filter and if true add it to a new results array.

Something like this (Pretty much the merriment of what I have + mikell) combines the concepts.  I tried just array delete without arrayuniqe and its terribly slow on a big array or just hung up on something for me.

#Include <File.au3>
#Include <Array.au3>

Local $sRoot = "C:"
Local $sFilter = "*.fit"

;All Files Recurse To Array
$aFiles = _FileListToArrayRec($sRoot, "*", $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)

If IsArray($aFiles) Then
    Local $aFinal[$aFiles[0]]

    For $i = 1 To $aFiles[0]
        $hSearch = FileFindFirstFile($aFiles[$i] & "\" & $sFilter)
        While 1
             $sFileName = FileFindNextFile($hSearch)
             If @error Then ExitLoop
            $aFinal[$i] = $aFiles[$i]
             ExitLoop
        Wend
        FileClose($hSearch)
    Next
EndIf

$aFinal2 = _ArrayUnique($aFinal)

For $i2 = UBound($aFinal2) -1 to 0 Step -1
 If $aFinal2[$i2] = "" Then _ArrayDelete($aFinal2, $i2)
Next
$aFinal2[0] = UBound($aFinal2) -1

_ArrayDisplay($aFinal2)

 

Edited by ViciousXUSMC
Link to comment
Share on other sites

Please mark this topic SOLVED.

Thanks to m23, mikell, and ViciousXUSMC.

I didn't state the problem clearly enough originally.

My top directory is named E:\Clif\Doublestar\      It contains a variable number of subdirectories with names like 2015_11_09_022752 BU_385AB 

The only "good" subdirectories contain at least one file with the .fit extension.

Here's the code that is now correctly selecting the good directories:

#include <File.au3>

Local $sTopDirectory = "E:\Clif\Doublestar\", $sSubdirectoryName, $sMaybeHit

; List folders within the root folder
$aList = _FileListToArray($sTopDirectory, Default, $FLTA_FOLDERS)
If IsArray($aList) Then
    For $a = 1 To $aList[0]
        $sSubdirectoryName = $sTopDirectory & $aList[$a]
        ConsoleWrite("Subdirectory Name: " & $sSubdirectoryName & @CRLF)
        ConsoleWrite("File pattern: " & $sSubdirectoryName & "\*.fit" & @CRLF)
        $sMaybeHit = "0"
        $hSearch = FileFindFirstFile($sSubdirectoryName & "\" & "*.fit")
        While 1
            $sFileName = FileFindNextFile($hSearch)
            If @error Then ExitLoop
            $sMaybeHit = $aList[$a] & "\" & $sFileName
            ConsoleWrite($aList[$a] & "\" & $sFileName & @CRLF)
            ExitLoop
        WEnd
        FileClose($hSearch)


        If Not ($sMaybeHit = "0") Then
            ConsoleWrite("Good hit" & @CRLF)
        Else
            ; No files matching the wildcard
            ConsoleWrite("Skip this folder" & @CRLF)
        EndIf

    Next

EndIf

Here's sample output:

Subdirectory Name: E:\Clif\Doublestar\2015_11_09_022752 BU_385AB
File pattern: E:\Clif\Doublestar\2015_11_09_022752 BU_385AB\*.fit
Skip this folder
Subdirectory Name: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus1
File pattern: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus1\*.fit
2015_11_09_022752 BU_bogus1\doublestar_2015_11_09_022752_1000.fit
Good hit
Subdirectory Name: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus2
File pattern: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus2\*.fit
Skip this folder
Subdirectory Name: E:\Clif\Doublestar\2015_11_09_023228 SAO73075
File pattern: E:\Clif\Doublestar\2015_11_09_023228 SAO73075\*.fit
2015_11_09_023228 SAO73075\doublestar_2015_11_09_023228_0000(2).fit
Good hit
Subdirectory Name: E:\Clif\Doublestar\2015_11_09_023228 SAObogus1
File pattern: E:\Clif\Doublestar\2015_11_09_023228 SAObogus1\*.fit
2015_11_09_023228 SAObogus1\doublestar_2015_11_09_023228_1983.fit
Good hit

I can confirm that the script did find the three good subdirectories, and it skipped the two that do not contain any .fit files.

Again thank you!

RaySS

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...