• Batch Script to move all but newest 3 files

    Home » Forums » Developers, developers, developers » DevOps Lounge » Batch Script to move all but newest 3 files

    • This topic has 20 replies, 7 voices, and was last updated 9 years ago.
    Author
    Topic
    #472112

    So just as the title says I’m looking to make a batch file that moves all but the newest 3 files from a folder to an External drive.

    Some background, I’m using Audacity (starting today) to record weekly meetings and I would like to keep only the most recent 3 recordings on my internal hard drive (for space reasons).
    I’m using Win7-32 bit (as it says in my siggy below)

    Viewing 15 reply threads
    Author
    Replies
    • #1248260

      You might look at VBScript and the FileSystemObject. I don’t have any sample code for this exact issue, but I’m attaching a script that scans a directory tree for files modified the previous day, builds a list of them, them submits the list to 7-zip to archive them. Although my list is not sorted by date and time, you might be able to piggyback on some of the date comparison code. Maybe.

      • #1248268

        You might look at VBScript and the FileSystemObject. I don’t have any sample code for this exact issue, but I’m attaching a script that scans a directory tree for files modified the previous day, builds a list of them, them submits the list to 7-zip to archive them. Although my list is not sorted by date and time, you might be able to piggyback on some of the date comparison code. Maybe.

        Thanks. I’m afraid I’ll have to do a bit of research to understand everything in this (I’ve only done some very basic batch scripting myself) but, it could prove a valuable reference.

    • #1248271

      I don’t have time to program this until later today, but the principle is to use the parameters of DIR to sort files in descending order of ‘file modified’ timestamp, and, in the copying subroutine, just ignore the first three (newest) files and copy all the rest. If you are familiar with BATch lines like

      Code:
      for /f %%a in ('dir c:source /o-d /b') do call :maybemove "%%a"

      then you’ve almost done the work yourself!

      BATcher

      Plethora means a lot to me.

    • #1248275

      Right, here you are!

      Code:
      @echo off
      setlocal
      :: change the next two statements to match what you want
      set srcdir=c:source
      set tgtdir=c:target
      if not exist %tgtdir%*.* md %tgtdir%
      set ctr=0
      for /f "tokens=*" %%a in ('dir "%srcdir%" /o-d /b') do call :maybemove "%%a"
      set /a ctr-=3
      echo %~n0: %ctr% files were moved from %srcdir% to %tgtdir%
      endlocal
      goto :eof
      ::--------------------
      
      :maybemove
      :: increment counter and bypass the three newest files
      set /a ctr+=1
      if %ctr% leq 3 goto :eof
      :: remove the double-quotes from the front and back of the filename
      set fn=%~1
      :: perform the move
      ECHO move /y "%srcdir%%fn%" "%tgtdir%"
      goto :eof
      

      Try it; when you are happy that it appears to do what you want, remove the ‘ECHO’ from in front of the ‘move’ statement to get it to actually do the work.

      Beware that BATch files are very susceptible to problems with so-called ‘poison characters’ in filenames, examples being ‘&’ and ‘%’, so you may wish to inspect your filenames and modify them to avoid such.

      I haven’t made any provision for the presence of any subdirectories in your source directory, and assume there are none.

      Finally, I would prefer to use XCOPY followed by DEL if the XCOPY errorlevel was zero, rather than MOVE, mainly because MOVE is more fussy. It should be OK here, though.

      Hope this fits your requirements!

      BATcher

      Plethora means a lot to me.

      • #1248420

        Right, here you are!

        Code:
        @echo off
        setlocal
        :: change the next two statements to match what you want
        set srcdir=c:source
        set tgtdir=c:target
        if not exist %tgtdir%*.* md %tgtdir%
        set ctr=0
        for /f "tokens=*" %%a in ('dir "%srcdir%" /o-d /b') do call :maybemove "%%a"
        set /a ctr-=3
        echo %~n0: %ctr% files were moved from %srcdir% to %tgtdir%
        endlocal
        goto :eof
        ::--------------------
        
        :maybemove
        :: increment counter and bypass the three newest files
        set /a ctr+=1
        if %ctr% leq 3 goto :eof
        :: remove the double-quotes from the front and back of the filename
        set fn=%~1
        :: perform the move
        ECHO move /y "%srcdir%%fn%" "%tgtdir%"
        goto :eof
        

        Try it; when you are happy that it appears to do what you want, remove the ‘ECHO’ from in front of the ‘move’ statement to get it to actually do the work.

        Beware that BATch files are very susceptible to problems with so-called ‘poison characters’ in filenames, examples being ‘&’ and ‘%’, so you may wish to inspect your filenames and modify them to avoid such.

        I haven’t made any provision for the presence of any subdirectories in your source directory, and assume there are none.

        Finally, I would prefer to use XCOPY followed by DEL if the XCOPY errorlevel was zero, rather than MOVE, mainly because MOVE is more fussy. It should be OK here, though.

        Hope this fits your requirements!

        Thanks, I’ll run a test with it later tonight (probably). The file names are going to be dates without slashes so numbers like 10072010 for recording taken on the tenth month, seventh day of the year 2010. In time I may modify this for similar operations. I failed to realize just how advanced a program you can make with batch files. I’ve been taking Java classes lately and have also done some P-Basic in the past (this is a lot closer to P-Basic of course) so when I read this it actually makes a lot of sense. I know in Java if I just used a user inputted string to select a directory I would have errors because of special characters meaning different things (for instance if I wanted the directory C:hihello in java I’d have to input it as C:\hi\hello or it would try to do whatever h means twice).

    • #1248427

      Here it is on one line if you want to play on the Command line.

      Code:
      for /f "skip=3 tokens=*" %X in ('dir "C:source}.*" /b /o:-d') do move /y "C:source%X" "E:destination"

      Change the “skip” number if you want more or less than 3 files.

      cheers, Paul

      • #1248440

        Here it is on one line if you want to play on the Command line.

        Code:
        for /f "skip=3 tokens=*" %X in ('dir "C:source}.*" /b /o:-d') do move /y "C:source%X" "E:destination"

        Change the “skip” number if you want more or less than 3 files.

        A one-liner in the tradition of APL, but you really should have tested it to get out the typo(s)!

        BATcher

        Plethora means a lot to me.

    • #1248597

      Test? What’s that? ;-))

      cheers, Paul

    • #1249009

      I ran a test and the program seems to work. I actually like the bigger batch file in this case because though it may take a couple more KB’s (if that) I can more easily follow it. I’ve learned over the few years I’ve been programming that smaller isn’t always better, sometimes having something bigger that’s easier to follow is a far better choice. This is especially true if you think you’ll be recycling the code for other uses or in the case of more advanced programming it’s common to update programs for either more functionality or better compatibility.

    • #1249040

      To be fair to Paul, incorporating his skip=3 parameter (if I had thought about it at the time) would have made my code slightly simpler…!

      BATcher

      Plethora means a lot to me.

    • #1249170

      Just go for the jugular, fair is for wooses!!

      cheers, Paul

      • #1559635

        Hi All,

        Greetings !

        The discussion above was quite helpful. I feel ashamed that I am copying the work you good people are doing. But anyways, it is helping me. I can only say Thank You !

        I was just wondering, if we need to move files with a particular extension ( here a notepad – .txt ), what changes should I make to your code ? [Where do I place the .txt]

        @echo off
        setlocal
        :: change the next two statements to match what you want
        set srcdir=c:source
        set tgtdir=c:target
        if not exist %tgtdir%*.* md %tgtdir%
        set ctr=0
        for /f “tokens=*” %%a in (‘dir “%srcdir%” /o-d /b’) do call :maybemove “%%a”
        set /a ctr-=3
        echo %~n0: %ctr% files were moved from %srcdir% to %tgtdir%
        endlocal
        goto :eof
        ::——————–

        :maybemove
        :: increment counter and bypass the three newest files
        set /a ctr+=1
        if %ctr% leq 3 goto :eof
        :: remove the double-quotes from the front and back of the filename
        set fn=%~1
        :: perform the move
        move /y “%srcdir%%fn%” “%tgtdir%”
        goto :eof

        Regards,

    • #1559690

      You need to add the file filter to the “dir” statement.
      for /f “tokens=*” %%a in (‘dir “%srcdir%*.txt” /o-d /b’) do call :maybemove “%%a”

      If you want to put code at the start of the batch file to allow you to easily change the filter copy the “set srcdir” bits and add it to the “dir” command – I’ll let you have a go and help if you have questions.

      cheers, Paul

    • #1559699

      Thanks so much. Worked perfectly !

      Regards

      Vik

    • #1559707

      I have another query. How to move files from one location, to two locations?

      I have written a batch, but it moves to only the first location (target1), and not the second.

      @echo off
      move /-y “c:source*.wav” “c:target1”
      move /-y “c:source*.wav” “c:target2”

      Please help. Appreciate your reply.

      Regards,

      Vik

    • #1559720

      When you move things from the source to target1 they are no longer in the source directory so cannot be moved again!

      You will need to use a copy operation.

    • #1559744

      copy /-y “c:source*.wav” “c:target1”
      move /-y “c:source*.wav” “c:target2”

      cheers, Paul

    • #1559804

      G.R.,

      Here’s a generalized solution using PowerShell. I think you’ll agree that it is much more understandable and since you can pass parameters much more flexible.

      Please note this is a long post because I wanted to show the actual results. You can just jump over the results if you trust my testing. ๐Ÿ˜†

      Note: I’m probably going to continue development of this code and will definatley add help.
      I’ll post updates to this thread as replies.

      Code:
      Param (
       [Parameter (Mandatory=$False)]
          [String] $Filter = "*.txt",     #Default file filter
       [Parameter (Mandatory=$False)] 
          [String] $FilePath = "G:Test", #Default directory
       [Parameter (Mandatory=$False)] 
             [Int] $FileCnt = 3,          #Default No. of files to keep
       [Parameter (Mandatory=$False)]
          [String] $Dest,                 #Where to Move Files
       [Parameter (Mandatory=$False)]
          [Switch] $Delete ,              #If Present Delete otherwise Move
       [Parameter (Mandatory=$False)]
          [Switch] $TestDebug
      )
      
      Clear-Host
      
      $FileList = Get-ChildItem -path $FilePath -Filter $Filter | 
                  Sort LastWriteTime 
      
      If (-not(Test-Path Variable:global:FileList))  { Exit }
      
      $LastIndex = $FileList.Count - $FileCnt - 1
       
      If ($TestDebug) {
        "-----------  Debug/Test Information   --------------"
        $FileList | Select Lastwritetime, name | Format-Table
        "Files in list: $($filelist.count) - Files to keep: $FileCnt"
        "Last Index Number: $($LastIndex)`n"
      }
      
      If ($FileList.Count -gt $FileCnt) {
      
        If ($Delete) {
          $Operation = "Deleted"
        }
        Else {
          $Operation = "Moved"
          If ($Dest -eq "") {
            $Dest = Read-Host "Please Provide Destination Directory!"
            If (-not(Test-Path $Dest)) {Exit}  #User did not supply a valid dest!
          }
        }
      
        ForEach ($File in $FileList[0..$LastIndex]) {
      
           If ($TestDebug) {
             "File to be $Operation : $($File.LastWriteTime)  $($File.Name)"
           }
           Else {
             If ($Delete) {
               $File.Delete()
             }
             Else {
               Move-Item -Path "$($File.FullName)" -Destination "$Dest" 
             }
           }
      
        } #End ForEach ($File...
      
        If ($TestDebug) {
          "`n        - Files Remaining on Disk -"
          $FileList[($LastIndex + 1)..($FileList.Count - 1)] | 
             Sort LastWriteTime | Select LastWriteTime, Name | 
             Format-Table
          "---------- End Debug/Test Information --------------"
        } #End If($TestDebug)
      
      } #End If $FileList...

      Sample Runs:

      Starting Directory Data:

      Code:
       Volume in drive G is Data
       Volume Serial Number is D2F3-1FE0
      
       Directory of g:Test
      
      04/12/2016  07:28 PM              .
      04/12/2016  07:28 PM              ..
      11/07/2010  10:07 PM             1,772 add-signature.ps1
      12/06/2013  09:24 AM             2,551 BEKTaskLists.ps1
      08/13/2011  10:02 PM             1,788 ChassisType2.ps1
      [COLOR="#0000FF"]04/01/2016  09:03 AM            79,732 CMsPCInfo.txt
      [/COLOR]04/10/2016  06:55 PM             8,447 CorpCommData.xlsx
      03/20/2016  09:26 AM                63 domains.csv
      [COLOR="#0000FF"]04/11/2016  03:15 PM             1,690 Dr Meter Scale.txt
      03/25/2016  01:19 PM               103 NetComputers.txt
      [/COLOR]04/12/2016  06:34 PM              Results
      [COLOR="#0000FF"]04/09/2016  03:08 PM               440 RoboFormDataHere.txt
      [/COLOR]12/16/2015  09:16 PM              SnapShots
      08/03/2015  06:40 AM              Test TSM
      04/12/2016  07:28 PM              TestFiles
      [COLOR="#0000FF"]02/22/2012  02:30 PM               870 VBA - Word - Attach Excel file as Data source for current document..txt
      01/05/2012  08:31 PM             1,108 VBA - Word - Highlight words in one doc in another.txt
      10/25/2011  11:11 AM               558 VBA - Word - Insert shape and give it a Name.txt
      08/16/2013  03:38 PM             1,166 VBA - Word - Print Only Pages containing specified phrase.txt
      11/15/2011  11:05 AM             1,541 VBA - Word - Return to last selected location.txt
      07/21/2011  09:11 AM               498 VBA Adding to LIST feature 2007-10.txt
      [/COLOR]03/18/2016  02:16 PM              WDPassTest
      [COLOR="#0000FF"]03/30/2016  02:36 PM             9,844 WSL Useful Post Links.txt
      [/COLOR]              16 File(s)        112,171 bytes
                     7 Dir(s)  458,538,995,712 bytes free
      

      Run with TestDebug switch:
      PS> .Delete-FilesExceptLastN.ps1 -FileCnt 5 -TestDebug -Dest “G:TestResults”

      Note: Above uses the Default Source Directory!

      Code:
      -----------  Debug/Test Information   --------------
      
      LastWriteTime          Name                                                    
      -------------          ----                                                    
      7/21/2011 9:11:25 AM   VBA Adding to LIST feature 2007-10.txt                  
      10/25/2011 11:11:03 AM VBA - Word - Insert shape and give it a Name.txt        
      11/15/2011 10:05:12 AM VBA - Word - Return to last selected location.txt       
      1/5/2012 7:31:28 PM    VBA - Word - Highlight words in one doc in another.txt  
      2/22/2012 1:30:33 PM   VBA - Word - Attach Excel file as Data source for cur...
      8/16/2013 3:38:53 PM   VBA - Word - Print Only Pages containing specified ph...
      3/25/2016 1:19:49 PM   NetComputers.txt                                        
      3/30/2016 2:36:21 PM   WSL Useful Post Links.txt                               
      4/1/2016 9:03:30 AM    CMsPCInfo.txt                                           
      4/9/2016 3:08:18 PM    RoboFormDataHere.txt                                    
      4/11/2016 3:15:13 PM   Dr Meter Scale.txt                                      
      
      
      Files in list: 11 - Files to keep: 5
      Last Index Number: 5
      
      File to be Moved : 07/21/2011 09:11:25  VBA Adding to LIST feature 2007-10.txt
      File to be Moved : 10/25/2011 11:11:03  VBA - Word - Insert shape and give it a 
      Name.txt
      File to be Moved : 11/15/2011 10:05:12  VBA - Word - Return to last selected loc
      ation.txt
      File to be Moved : 01/05/2012 19:31:28  VBA - Word - Highlight words in one doc 
      in another.txt
      File to be Moved : 02/22/2012 13:30:33  VBA - Word - Attach Excel file as Data s
      ource for current document..txt
      File to be Moved : 08/16/2013 15:38:53  VBA - Word - Print Only Pages containing
       specified phrase.txt
      
              - Files Remaining on Disk -
      
      LastWriteTime        Name                     
      -------------        ----                     
      3/25/2016 1:19:49 PM NetComputers.txt         
      3/30/2016 2:36:21 PM WSL Useful Post Links.txt
      4/1/2016 9:03:30 AM  CMsPCInfo.txt            
      4/9/2016 3:08:18 PM  RoboFormDataHere.txt     
      4/11/2016 3:15:13 PM Dr Meter Scale.txt       
      
      ---------- End Debug/Test Information --------------
      

      Source Directory after run:

      Code:
       Volume in drive G is Data
       Volume Serial Number is D2F3-1FE0
      
       Directory of g:Test
      
      04/12/2016  07:39 PM              .
      04/12/2016  07:39 PM              ..
      11/07/2010  10:07 PM             1,772 add-signature.ps1
      12/06/2013  09:24 AM             2,551 BEKTaskLists.ps1
      08/13/2011  10:02 PM             1,788 ChassisType2.ps1
      [COLOR="#0000FF"]04/01/2016  09:03 AM            79,732 CMsPCInfo.txt
      [/COLOR]04/10/2016  06:55 PM             8,447 CorpCommData.xlsx
      03/20/2016  09:26 AM                63 domains.csv
      [COLOR="#0000FF"]04/11/2016  03:15 PM             1,690 Dr Meter Scale.txt
      03/25/2016  01:19 PM               103 NetComputers.txt
      [/COLOR]04/12/2016  07:39 PM              Results
      [COLOR="#0000FF"]04/09/2016  03:08 PM               440 RoboFormDataHere.txt
      [/COLOR]12/16/2015  09:16 PM              SnapShots
      08/03/2015  06:40 AM              Test TSM
      04/12/2016  07:28 PM              TestFiles
      03/18/2016  02:16 PM              WDPassTest
      [COLOR="#0000FF"]03/30/2016  02:36 PM             9,844 WSL Useful Post Links.txt
      [/COLOR]              10 File(s)        106,430 bytes
                     7 Dir(s)  458,538,987,520 bytes free
      
      

      Destination Directory:

      Code:
       Volume in drive G is Data
       Volume Serial Number is D2F3-1FE0
      
       Directory of g:TestResults
      
      04/12/2016  07:41 PM              .
      04/12/2016  07:41 PM              ..
      [COLOR="#0000FF"]02/22/2012  02:30 PM               870 VBA - Word - Attach Excel file as Data source for current document..txt
      01/05/2012  08:31 PM             1,108 VBA - Word - Highlight words in one doc in another.txt
      10/25/2011  11:11 AM               558 VBA - Word - Insert shape and give it a Name.txt
      08/16/2013  03:38 PM             1,166 VBA - Word - Print Only Pages containing specified phrase.txt
      11/15/2011  11:05 AM             1,541 VBA - Word - Return to last selected location.txt
      07/21/2011  09:11 AM               498 VBA Adding to LIST feature 2007-10.txt
      [/COLOR]               6 File(s)          5,741 bytes
                     2 Dir(s)  458,538,983,424 bytes free
      

      HTH :cheers:

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1560895

      Hey Y’all,

      As promised here is the “almost” completed project. I’m still working on directory recursion!

      This version will move files as the default but will delete them with the -Delete switch.
      You can set the number of files to keep.
      You can have the program tell you what it would do w/o actually changing anything.

      For full operating instructions enter:

      get-help .MovDel-FilesExceptLastNDev.ps1 -Full

      at the PowerShell prompt if you have unzipped the file to your default PS directory. If not replace the . with the complete drivepath to the file.

      Zipped Program File: 44245-MovDel-FilesExceptLastN

      As always comments on the code/functionality are welcome in my PowerShell learning quest.

      HTH :cheers:

      May the Forces of good computing be with you!

      RG

      PowerShell & VBA Rule!
      Computer Specs

    • #1560901

      Thanks a million !

    Viewing 15 reply threads
    Reply To: Reply #1559744 in Batch Script to move all but newest 3 files

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information:




    Cancel