Reputation: 9
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
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
Reputation: 38755
What you shouldn't do: Don't let you be hoodwinked into
What you should do:
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.
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?
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.]
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).
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
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