rumour Posted June 5, 2007 Share Posted June 5, 2007 Hi all! This should be an easy one for all of you programmers out there... I have a directory of .pdf files, each with a name and a series number, i.e.: file_01.pdf file_02.pdf text_01.pdf text_02.pdf text_03.pdf document_01.pdf document_02.pdf I'm trying to build an array of each set of files, i.e.: array1 = file_01.pdf, file_02.pdf array2 = text_01.pdf, text_02.pdf, text_03.pdf array3 = document_01.pdf, document_02.pdf The code I've written works until I reach the last file in the directory. I'm running into a problem with the line... $comp2=StringSplit($bdOFL[$y+1],"_") ...it breaks when $y + 1 goes greater than the number of files in the the directory. Here's the code: #include <file.au3> #include <string.au3> #include <array.au3> HotKeySet("^!x", "MyExit"); hotkey to exit = CTRL+ALT+X $bdSD = "C:\Practice Folder\" $bdOFL = _FileListToArray($bdSD,"*.pdf"); build an array of files in the source directory $x=$bdOFL[0]; number of files in source directory $y = 1; current position counter While $y < $x+1 Dim $bdFL[100]; unlikely to group more than 100 files $z=1; number of files in current grouping Do $bdFL[$z-1]=$bdOFL[$y] $comp1=StringSplit($bdOFL[$y],"_"); loads filename up to the underscore $comp2=StringSplit($bdOFL[$y+1],"_"); loads filename up to the underscore $z=$z+1 $y=$y+1 Until $comp1[1]<>$comp2[1]; are the filenames up to the underscore different? ReDim $bdFL[$z-1] _ArrayDisplay($bdFL,"$bdFL"); debug code WEnd Func MyExit() Exit EndFunc Any suggestions? Thanks in advance! Brian Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 5, 2007 Share Posted June 5, 2007 Why not just use better wildcard patterns and get them straight to the arrays? #include <file.au3> #include <array.au3> Global $bdSD = "C:\Practice Folder\" $avFileList = _FileListToArray($bdSD, "file_*.pdf") $avTextList = _FileListToArray($bdSD, "text_*.pdf") $avDocList = _FileListToArray($bdSD, "document_*.pdf") $TotalFiles = $avFileList[0] + $avTextList[0] + $avDocList[0] If MsgBox(64 + 4, "Results", "There are a total of " & $TotalFiles & " selected .pdf files." & @CRLF & _ "file_*.pdf files: " & $avFileList[0] & @CRLF & _ "text_*.pdf files: " & $avTextList[0] & @CRLF & _ "document_*.pdf files: " & $avDocList[0] & @CRLF & _ "Do you want to see them listed?") = 6 Then _ArrayDisplay($avFileList, "file_*.pdf files") _ArrayDisplay($avTextList, "text_*.pdf files") _ArrayDisplay($avDocList, "document_*.pdf files") EndIf Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
rumour Posted June 5, 2007 Author Share Posted June 5, 2007 Well...perhaps I was too generic with my problem statement. The working directory has lots of different files with different names. They all take the format of name datestamp_##.pdf, but I don't think setting up standing wildcards is what I want to do. Here's a list of actual files in the working directory: ATT 20070405_1.PDF ATT 20070405_2.PDF ATT 20070405_3.PDF Chase MC 20070412_1.PDF Chase MC 20070412_2.PDF Dish Network 20070511_1.PDF Dish Network 20070511_2.PDF GECU 20070331_1.PDF GECU 20070331_2.PDF GPFCU 20070331_1.PDF GPFCU 20070331_2.PDF Here's the Menu_1.PDF Here's the Menu_2.PDF Here's the Menu_3.PDF Here's the Menu_4.PDF Here's the Menu_5.PDF JCAD Notice of Appraised Value 20070423_1.PDF JCAD Notice of Appraised Value 20070423_2.PDF LPM 20070508_1.PDF LPM 20070508_2.PDF OSB 20070405_1.PDF OSB 20070405_2.PDF OSB 20070405_3.PDF OSB 20070405_4.PDF OSB 20070505_1.PDF OSB 20070505_2.PDF OSB 20070505_3.PDF OSB 20070505_4.PDF Save the Earth While Saving Some Money_1.PDF Save the Earth While Saving Some Money_2.PDF Save the Earth While Saving Some Money_3.PDF Save the Earth While Saving Some Money_4.PDF Trailer Title_1.PDF Trailer Title_2.PDF Trailer Title_3.PDF This is a partial list. The purpose of my original script is to form arrays, which will be used to make delimited strings, which will be fed to a program to combine each group of .pdfs into a single .pdf. So, once I process these files, I will eventually re-fill the directory with new files (with different file names). Sorry for the confusion. Brian Link to comment Share on other sites More sharing options...
weaponx Posted June 5, 2007 Share Posted June 5, 2007 This will be tricky since some files in your examples have timestamps and some don't. Link to comment Share on other sites More sharing options...
Zedna Posted June 5, 2007 Share Posted June 5, 2007 Use _FileListToArray($bdSD, "*.pdf") to have all files in one array. Then sort this array: _ArraySort() Now go throug tjat array and test whether name without last character is the same as previous array item If YES then it's one group else start new group. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
weaponx Posted June 6, 2007 Share Posted June 6, 2007 I threw this together for you, it only matches filenames if the datestamps AND the title match, just run it in the folder with all of your files expandcollapse popup#include <Array.au3> ; Shows the filenames of all files in the current directory. $search = FileFindFirstFile("*.PDF") Dim $ARRAY[1] $last = "" Dim $X = 0 ; Check if the search was successful If $search = -1 Then MsgBox(0, "Error", "No files/directories matched the search pattern") Exit EndIf ;Loop until error While 1 $file = FileFindNextFile($search) If @error Then ExitLoop ;Return portion of file name before underscore $splitfilename = StringSplit ( $file, "_" ) ;If beginning of filename matches beginning of last filename If $splitfilename[1] = $last Then ;Concat current filename to last array element with comma $ARRAY[Ubound($ARRAY) - 1] &= "," & $file ;If no match, create a new array element Else ;Manually assign first element, due to ARRAYADD skipping element zero If $X = 0 Then $ARRAY[$X] = $file Else _ArrayAdd( $ARRAY, $file) EndIf $X += 1 EndIf ;Update last file name $last = $splitfilename[1] WEnd ;Display array _ArrayDisplay ( $ARRAY, "ARRAY CONTENTS") ; Close the search handle FileClose($search) Link to comment Share on other sites More sharing options...
rumour Posted June 6, 2007 Author Share Posted June 6, 2007 Thanks weaponx! I tried your code. Slight modification, and viola! While it doesn't do what I was originally attempting (separate array for each set of files), I can use it's output quite easily. Thanks again. Brian Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 6, 2007 Share Posted June 6, 2007 Well...perhaps I was too generic with my problem statement. The working directory has lots of different files with different names. They all take the format of name datestamp_##.pdf, but I don't think setting up standing wildcards is what I want to do. Here's a list of actual files in the working directory: This is a partial list. The purpose of my original script is to form arrays, which will be used to make delimited strings, which will be fed to a program to combine each group of .pdfs into a single .pdf. So, once I process these files, I will eventually re-fill the directory with new files (with different file names). Sorry for the confusion. Brian I saved your list to Test_1.txt and ran this on it: #include <file.au3> $hFile = FileOpen("Test_1.txt", 0) While 1 $Line = FileReadLine($hFile) If @error Then ExitLoop _FileCreate("C:\Temp\" & $Line) WEndoÝ÷ Ù*«ÞÊ«{¶X¬¶ßW¬p´÷dÞh¦V²Â+aN¬~éܶ*'+Þ³*.jX¬¶è맫~)^©®-²Ú-ë§uêìrÞªê-ªê-jëh×6#include <file.au3> #include <array.au3> $TargetDir = "C:\Temp" $avNameList = _ListPDFs($TargetDir) _ArrayDisplay($avNameList, "List of PDF name roots") Func _ListPDFs($sDir) Local $avFiles = _FileListToArray($sDir, "*.pdf", 1) _ArraySort($avFiles, 0, 1) ; Sort ascending from [1] Local $n For $n = 1 To $avFiles[0] $avFiles[$n] = StringLeft($avFiles[$n], StringInStr($avFiles[$n], "_")) Next For $n = $avFiles[0] To 1 Step - 1 If $avFiles[$n] = "" Or $avFiles[$n] = $avFiles[$n - 1] Then _ArrayDelete($avFiles, $n) Next $avFiles[0] = UBound($avFiles) - 1 Return $avFiles EndFunc ;==>_ListPDFs Hope that helps. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
weaponx Posted June 6, 2007 Share Posted June 6, 2007 Glad I could help. Also there is no way to create arrays dynamically, at runtime, so you have to have an array with each element being a CSV string. Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 6, 2007 Share Posted June 6, 2007 Also there is no way to create arrays dynamically, at runtime, so you have to have an array with each element being a CSV string. Well, not that it's applicable to this topic, but that's actually one of the few useful things I can imagine about arrays in arrays. You can use _ArrayAdd() to add elements to a single array, and each of those elements can contain a copy of a dynamic array from something like _FileReadToArray() or IniReadSection(). You can iterate through the parent array, copying out each element to a working array. There are, of course, speed and resource penalties for doing it that way... but it can be done. This demo reads the contents of all .txt files in a directory to an array, then saves the arrays in an array. After a prompt, it reads each array out of the parent array and displays them: #include <array.au3> #include <file.au3> Global $avFiles[1] = [0] _TxtArrayAddDir(@DocumentsCommonDir) If MsgBox(32 + 4, "Question", "Do you want to see the contents of all " & $avFiles[0] & " .txt files?") = 6 Then _TxtArrayDisplay() EndIf ; Add FileReadToArray arrays of .txt files to the $avFiles array Func _TxtArrayAddDir($sDir) Local $FileName, $avFileList, $avWorking For $FileName In _FileListToArray($sDir, "*.txt", 1) If IsNumber($FileName) Then $avFiles[0] = $avFiles[0] + $FileName ; Save count ContinueLoop EndIf _FileReadToArray($sDir & "\" & $FileName, $avWorking) $avWorking[0] = $sDir & "\" & $FileName _ArrayAdd($avFiles, $avWorking) Next EndFunc ;==>_TxtArrayAddDir ; List contents of each array in the $avFiles array Func _TxtArrayDisplay() Local $avWorking, $FileName For $avWorking In $avFiles If Not IsArray($avWorking) Then ContinueLoop $FileName = $avWorking[0] $avWorking[0] = UBound($avWorking) - 1 _ArrayDisplay($avWorking, $FileName) Next EndFunc ;==>_TxtArrayDisplay Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
rumour Posted June 6, 2007 Author Share Posted June 6, 2007 PsaltyDS - one of my next steps was to build a filename for each group of consolidated files - obviously I'd use the left part of the filename up to the underscore. I was going to play around with this, but you've basically solved that for me - thanks! Link to comment Share on other sites More sharing options...
rumour Posted June 7, 2007 Author Share Posted June 7, 2007 Actually, I have another question for PsaltyDS and Zedna - I noticed that both of you use or suggest _ArraySort(). It seems that _FileListToArray() will build a sorted array (I assume because windows lists files alphabetically). Is there a reason to add _ArraySort(), or a time when you can't depend on _FileListToArray() to build a sorted array? Brian Link to comment Share on other sites More sharing options...
PsaltyDS Posted June 7, 2007 Share Posted June 7, 2007 Actually, I have another question for PsaltyDS and Zedna - I noticed that both of you use or suggest _ArraySort(). It seems that _FileListToArray() will build a sorted array (I assume because windows lists files alphabetically). Is there a reason to add _ArraySort(), or a time when you can't depend on _FileListToArray() to build a sorted array?Never, never, never trust a Microsoft product to do something consistent and logical like always listing the files in order... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
rumour Posted June 8, 2007 Author Share Posted June 8, 2007 Never, never, never trust a Microsoft product to do something consistent and logical like always listing the files in order... Touche - I'll update my code appropriately.Thanks again for your help. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now