dkrider471
dkrider471

Reputation: 9

Batch file to find all images and copy to a folder

Not even sure if this is possible, but I'd figured i'd give it a try.

So here's my problem. I need to search multiple big hard drives (1TB and bigger) for all images and move them to one folder. My issue i'm having is no matter what language I try to write this in I can't seem to figure out a answer. I either want it to be vbs or bat related not using the robocopy command. Some of my drives are all different formats such as fat32 and ntfs. My issue with a few scripts I tried with the batch file was my file names are too long. So the main functions I need it to do is find the images, copy them, rename them with a _001 _002 if they exist, count how many files are moved, and then finally delete them or move them to a seperate folder for deleting ( a little more safe in my eyes ). Any help would be appreciated because I am totally stumped on this.

Here is one script that I was working on but just stopped on. The problem with this is it copied the files, but did not keep the extension for some reason. This was one I found online and modified the code on a little. I'm very familiar with code, but for some reason can't seem to figure this out.

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set TESTFOLDER=allpictures
md "%TESTFOLDER%"


set /a counter=0
FOR /F "tokens=*" %%i IN ('DIR /S /B /A-D C:\Users\user1\Desktop\*.jpg') DO FOR /F "tokens=*" %%j IN ('DIR /B "%%i"') DO IF EXIST ".\%TESTFOLDER%\%%j" (
        set /a counter=!counter!+1
        echo folder: %TESTFOLDER%
        copy "%%i" ".\%TESTFOLDER%\%%j_!counter!"
    ) ELSE copy /B "%%i" ".\%TESTFOLDER%\%%j"
:eof

Edit: VBScript Code Below

Set fso = CreateObject("Scripting.FileSystemObject")

testfolder = ".\allpictures"
'fso.CreateFolder(testfolder)

CopyFiles fso.GetFolder("E:\")

Sub CopyFiles(fldr)
  For Each f In fldr.Files
    basename  = fso.GetBaseName(f)
    extension = fso.GetExtensionName(f)
    If LCase(extension) = "jpg" Then
      dest  = fso.BuildPath(testfolder, f.Name)
      count = 0
      Do While fso.FileExists(dest)
        count = count + 1
        dest  = fso.BuildPath(testfolder, basename & "_" & count & "." _
          & extension)
      Loop
      f.Copy dest
    End If
  Next

  For Each sf In fldr.SubFolders
    CopyFiles sf
  Next
End Sub

Upvotes: 0

Views: 9957

Answers (3)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200373

It's overkill to install a new script interpreter for something that can easily be handled by the script interpreters shipped with the operating system.

The reason why your script doesn't maintain the extension is because you append the content of the counter variable at the end of the file name, so foo.jpg becomes foo.jpg1 for a counter value of 1. You have to work with modifiers to avoid that: %%~nj gives you just the name of the file (without path and extension), %%~xj just the extension. Also, you probably don't want a single counter for all files, but one counter per duplicate file name.

@echo off

setlocal EnableDelayedExpansion

set TESTFOLDER=allpictures
md "%TESTFOLDER%"

for /f "tokens=*" %%i in ('dir /s /b /a-d C:\Users\user1\Desktop\*.jpg') do (
  call :copyfile "%%~i"
)

goto :eof

:copyfile
set fname=%~nx1
set counter=0

if not exist ".\%dest%\!fname!" goto docopy

:recheck
if exist ".\%dest%\%~n1_!counter!%~x1" (
  set /a counter+=1
  goto recheck
)
set fname=%~n1_!counter!%~x1

:docopy
copy "%~1" ".\%dest%\!fname!"

goto :eof

endlocal

In VBScript you could do something like this:

Set fso = CreateObject("Scripting.FileSystemObject")

testfolder = ".\allpictures"
fso.CreateFolder(testfolder)

CopyFiles fso.GetFolder("C:\Users\user1\Desktop")

Sub CopyFiles(fldr)
  For Each f In fldr.Files
    basename  = fso.GetBaseName(f)
    extension = fso.GetExtensionName(f)
    If LCase(extension) = "jpg" Then
      dest  = fso.BuildPath(testfolder, f.Name)
      count = 0
      Do While fso.FileExists(dest)
        count = count + 1
        dest  = fso.BuildPath(testfolder, basename & "_" & count & "." _
          & extension)
      Loop
      f.Copy dest
    End If
  Next

  For Each sf In fldr.SubFolders
    CopyFiles sf
  Next
End Sub

Upvotes: 1

Ekkehard.Horner
Ekkehard.Horner

Reputation: 38755

What you shouldn't do: Don't let you be hoodwinked into

  1. producing code before you have understood the problem in full and have a detailed plan about the procedure. (Nobody likes "give me a program to solve my problem" type of questions, and sometimes a code snippet may clarify a problem, but asking people to try what they admittedly can't do is poor didactic.)
  2. start with a new language to solve the problem at hand (plan or no plan). (If you are stuck writing a love letter in your native language, what are the chances to get it right with a grammar and a vocabulary of a foreign one?)

What you should do:

  1. Think about your problem with a focus on the ultimate aim: organizing your images (if I understand your comment correctly). How would that look like? Certainly not one folder with thousands of files with mangled names. I would strive to end with a folder tree containing .jpgs with decent names, or a database with suitable meta-info about my pictures (videos?) and pathes to their storage, or even an upload to some cloud storage. From that ultimate aim work backwards: what do you need in the previous step.

  2. I assume, the very first step is a list of all your .jpgs. What is - given your knowledge, skills, and tools - the easiest way to get this list? Probably some variation of dir /s [/b] c:\*.jpg > jpglist.txt. For many drives or other extensions that come up later, you can combine many such lines in one .cmd file (>/>>). This list and a text editor or a bit of filtering and a spreadsheet can give you valuable information about your task: How many files? Sum of all sizes? Duplicate files names? Possible classifications?

  3. Buy a new external drive (you know the size by now). That way you can postpone the deleting to the step after you presented your beautifully organized collection to the astonished audience. [And this last task would be trivial: Just feed your jpglist.txt thru a "delete" filter script or use the search and replace facility of your text editor to put "del /Q " at the beginning of the lines.]

  4. Depending on your needs and skills you can transform the basic jpglist.txt into new .csv files with pertinent information, that can be manually scanned/checked via a spreadsheet program and/or programmatically use to generate file or folder names (appending numbers should be the last fallback). If you'd like some JPG metadata and don't know how, you can ask here (and then even show the code you used to get sizes or dates for those files).

  5. Make each step repeatable and as non-destructive as possible (e.g. don't move or delete files you can't recreate with one command before you are all done). Use the techniques/tools you know; that definitely rules out "code found on the internet"); if you want to learn something new/more interesting then do it in a toy project.

Upvotes: 3

Benjamin Trent
Benjamin Trent

Reputation: 7566

If utilizing perl, you could glob all of the files in a given directory an put them in an array. my @Files = glob '<directory>\*.jpg';

The go through each file with a loop foreach $file (@Files){ ... }

Each .jpg would be referred to as $file in the loop. You can get the file name by my ($originalfilename) = $file; and add any extension you want then copy/move it to any other directory you want. Also, in that loop, you can increment your counter loop or just get the scalar value of the array.

There is a ton of stuff on HERE for perl documentation and tutorials all over the internet. It is worth learning some basic perl if file manipulation is going to be common place.

Upvotes: -2

Related Questions