Avatar of dds110
dds110
 asked on

Search and Replace in Multiple Sub-Directories

Hi,

I recently set up an intranet site where I work and before I noticed a small problem with my asp files, the management team that set up the directory structure went nuts and created tons of sub-directories.

Here's the problem:  Each sub-directory has a file named "default.asp" in it.  What I need to do is delete this file in each and every stinking sub-directory and copy a new one in its place.

I know how to delete and move files in vb.  What I don't know how to do is search in every single sub-directory.

Any suggestions?  I need VBScript.  If that's not a solution, the only other programming tool I have at work is office vba.

Thanks
Microsoft Access

Avatar of undefined
Last Comment
rockiroads

8/22/2022 - Mon
AndyAmess




you can drop to Dos and use the commands there.

i.e.

c:
cd \temp\mydirs
Delete default.asp /s

this will delete all files called default.asp from the directory c:\temp\mydirs\   and from all the sub directories below it.

the /s is the switch for dubdirectories and you should be able to use it for copying and moving too.



rockiroads

a small bit of VB code to traverse thru directories

Public Sub StartIt()

    Dim sFile As String

    sFile = "C:\StartDirectory"
   
    CheckDir sFile
End Sub


Public Sub CheckDir(ByVal sDir As String)

    Dim sFile As String
   
    'Read all until no files/dir left to process in this directory
    sFile = Dir(sDir & "\*.*", vbDirectory)
    Do While sFile <> ""
       
        If sFile = "default.asp" Then
            'Do whatever
       
        ElseIf sFile <> "." And sFile <> ".." Then
       
            'If directory, then go into this directory and process
            If (GetAttr(sDir & "\" & sFile) And vbDirectory) = vbDirectory Then
                CheckDir sDir & "\" & sFile
            End If
        End If
        sFile = Dir
    Loop
End Sub
AndyAmess

Yeah I knew in my heart that I should have given a procedure that calls itself until it runs out of directories.

rockiroads is the way to go.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
fcco

selfrecursion does the trick, sometimes selfrecursion can make things a lot simpler .

Good comment rockiroads!
rockiroads

gosh, all these compliments, getting quite embarrased now

ta guys
dds110

ASKER
code looks great, but doesn't work quite right.

When I run it (i'm stepping through a set of test directories), It finds the first sub-dir, moves into it, finds the next sub-dir, moves into it, finds the last sub-dir, replaces my test file and then fails.

I'm trying right now to rework the code but if you have any ideas, they'd be appreciated.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
rockiroads

what does it fail with,
dds110

ASKER
I've marked the line it fails on.  The error is Invalid Procedure or argument.  It only fails after it's looped through each sub-directory.

Public Sub CheckDir(ByVal sDir As String)

   Dim sFile As String
   
   'Read all until no files/dir left to process in this directory
   sFile = Dir(sDir & "\*.*", vbDirectory)
   Do While sFile <> ""
       
       'If sFile = "default.asp" Then
       If sFile = "blah.txt" Then
           'Do whatever
           FileCopy "C:\blah\newblah.txt", sFile
       
       ElseIf sFile <> "." And sFile <> ".." Then
       
           'If directory, then go into this directory and process
           If (GetAttr(sDir & "\" & sFile) And vbDirectory) = vbDirectory Then
               CheckDir sDir & "\" & sFile
           End If
       End If
       sFile = Dir '*********Fails Here*************
   Loop
End Sub
dds110

ASKER
AndyAmess

I liked your idea and I could get the Del /s command to work but that's it.

The copy command doesn't take the /s switch
The replace command keeps telling me it can't find the path to my new file...

I don't get that last one?!?

Still trying though.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
fcco

i think it's a casting error try dim sFile instead of dim sFile as string
 
dds110

ASKER
Oh yeah, here's what I tried for the replace command

C:\blah>replace blah.txt /s newblah.txt
Path not found - C:\blah\newblah.txt
No files replaced

I even tried this:

C:\blah>replace blah.txt /s c:\blah\newblah.txt
Path not found - C:\blah\newblah.txt
No files replaced

Here's my tree:
C:\blah>tree
Folder PATH listing
Volume serial number is 0006FE80 78FF:9687
C:.
„¤„Ÿ„Ÿ„Ÿblah
    „¤„Ÿ„Ÿ„Ÿblah
dds110

ASKER
fcco:

Same error, same line

boy that last paste I did didn't work quite right did it?

My tree looks like this (this is my simple test directory)

C:\Blah
C:\Blah\Blah
C:\Blah\Blah\Blah

C:\Blah contains blah.txt and newblah.txt
Each other directory contains blah.txt
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
rockiroads

sorry about getting back late

Ive had a look, I got similar code which I wrote sometime ago, so I cant see whats the problem, I just tried my suggested code and get the error, maybe there is a difference in VB and VBA, shouldnt be but who knows


if you want an alternative (bit more advaned in terms of coding)
its VB but should still work

have a look at this

http://vbnet.mvps.org/index.html?code/fileapi/recursivefiles%5Fminimal.htm
http://vbnet.mvps.org/index.html?code/fileapi/recursivefolders%5Fminimal.htm
rockiroads

try this

Private Type WIN32_FIND_DATA
   dwFileAttributes As Long
   ftCreationTime As FILETIME
   ftLastAccessTime As FILETIME
   ftLastWriteTime As FILETIME
   nFileSizeHigh As Long
   nFileSizeLow As Long
   dwReserved0 As Long
   dwReserved1 As Long
   cFileName As String * 260
   cAlternate As String * 14
End Type

Private Declare Function FindClose Lib "kernel32" _
  (ByVal hFindFile As Long) As Long
   
Private Declare Function FindFirstFile Lib "kernel32" _
   Alias "FindFirstFileA" _
  (ByVal lpFileName As String, _
   lpFindFileData As WIN32_FIND_DATA) As Long
   
Private Declare Function FindNextFile Lib "kernel32" _
   Alias "FindNextFileA" _
  (ByVal hFindFile As Long, _
   lpFindFileData As WIN32_FIND_DATA) As Long

Private Declare Function lstrlen Lib "kernel32" _
    Alias "lstrlenW" (ByVal lpString As Long) As Long

private const vbDot = 46

Public Sub CheckDir3(sRoot As String)

   Dim wfd As WIN32_FIND_DATA
   Dim hFile As Long
 
   hFile = FindFirstFile(sRoot & "*.*", wfd)
 
   If hFile <> -1 Then
   
      Do
                 
         If Asc(wfd.cFileName) <> vbDot Then
            If (wfd.dwFileAttributes And vbDirectory) Then
           
               CheckDir3 sRoot & TrimNull(wfd.cFileName) & "\"
           
            Else
                If InStr(1, wfd.cFileName, "default.asp") > 0 Then
                    'do whatever
            End If
           
         End If
     
      Loop While FindNextFile(hFile, wfd)
   
   End If 'If hFile
 
   Call FindClose(hFile)

End Sub


Private Function TrimNull(startstr As String) As String
   TrimNull = Left$(startstr, lstrlen(StrPtr(startstr)))
End Function

rockiroads

I cant see why the Dir bit is not working
Gonna load it up on VB and check it
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
dds110

ASKER
I found something in the MS Access help files (surprise) that did the trick perfectly.  Here's the code:

If no has any problems, i'm gonna ask the mods to paq this q.  Please let me know.

******************the code******************************************
Function searchandreplace()
'must hava a reference set to the ms office object library for this to work
Dim i As Integer
With Application.FileSearch
    .NewSearch
    .LookIn = "L:\Inetpub\JCSC\Supervisor Reports"
    .SearchSubFolders = True
    .MatchTextExactly = True
    .FileName = "default.asp"
    .FileType = msoFileTypeAllFiles
   
    If .Execute() > 0 Then
        MsgBox "There were " & .FoundFiles.Count & _
            " file(s) found."
        For i = 1 To .FoundFiles.Count
'            MsgBox .FoundFiles(i)
              If Right(.FoundFiles(i), 12) = "\default.asp" Then
                Debug.Print .FoundFiles(i)
                FileCopy "L:\Inetpub\JCSC\Supervisor Reports\zdefault.asp", .FoundFiles(i)
              End If
        Next i
    Else
        MsgBox "There were no files found."
    End If
End With
   
End Function
***********************end the code********************************

Thanks for all the help anyway.
dds110

ASKER
Oh yeah, thought I'd let everyone know that there were 246 sub-directories.

I'm really glad I didn't have to do this by hand.
ASKER CERTIFIED SOLUTION
PashaMod

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
rockiroads

to dds10
regarding the method using dir and getting the error, I now realise the error

it should be
   sFile = Dir(sDir, vbDirectory)

and not

   sFile = Dir(sDir & "\*.*", vbDirectory)
 

just recently realised my mistake, just thought i'd let you know even though I know you got your own solution
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.