Add numbering to multiple folders - batch-file

So I have a lot of folders(1000+) and I want to add an incrementing number at the start of each one of them. The folder names contain spaces. I am on windows 10.
Example of folder names:
Folder number-one
Folder number-two
Folder number-three
Output wanted:
1000_Folder number-one
1001_Folder number-two
1002_Folder number-three
I've looked for similar articles but I didn't find something for my particular case.

The following code will rename all folders in c:\flrtest beginning with the letter "f" to an incremented number beginning with 1000.
I wrote it with the "f" restriction for two reasons:
(1) in case there were folders you did not want to change. To change all folders in c:\flrtest then just change line 3 from "c:\flrtest\f*" to "c:\flrtest"
(2) Allows running the script more than once without ill effect. If the "f" restriction is removed and the script is run more than once over the same set of directories it will yield results you probably don't want. The directories will end up with names such as "1000_1000_folderA" etc.
Since your folder will likely be somewhere other than "c:\flrtest" then just change this location in lines 3 & 7.
Hopefully this helps.
#echo off
set inc=1000
for /f "delims=" %%i in ('dir /a:d /b "c:\flrtest\f*"') do call :RenDir "%%i"
exit /b
:RenDir
ren "c:\flrtest\%~1" "%inc%_%~1"
set /a inc=inc+1
exit /b
Before running
After running
Removing the "f" restriction and running twice. Not so good.

Related

Will this be possible with a batch file?

Before I start posting code I am wondering if this is even feasible.
I have a directory of folders I need to move to a new directory.
But I only need to move the folders that contain only 2 files in them.
The rest of the folders have more than 2 files in them, but they need to stay.
So would this be feasible with a batch file?
This was interesting so I took a stab at it:
#echo off
set "dir=C:\Your\Current\Directory"
set "ndir=C:\Your\New\Directory"
setlocal enabledelayedexpansion
for /d %%A in (%dir%\*) do (
pushd "%%A"
for /f %%B in ('dir /a-d-s-h /b ^| find /v /c ""') do (
set cnt=%%B
if "!cnt!" == "2" (if not exist "%ndir%\%%~nA" robocopy "%%A" "%ndir%\%%~nA" /e)
)
)
pause
I kept running into issues so I modified a few things to make it do what I wanted; there're likely more elegant ways to go about it, but this worked ¯\_(ツ)_/¯. First thing is setting variables for your current directory (dir) and your new directory (ndir) to make it a little easier to digest later on; we also need to enable delayed expansion since the value of our counting variable (cnt) will change between loop iterations. The first FOR loop is /d, which will loop through folders - we set each of those folders as parameter %%A and use that to change our directory (using pushd) prior to running our nested commands.
The second FOR loop is /f, which will loop through command results - the commands in this case being dir and find. For dir we are specifying /a to show all files that -d aren't folders, -s system files, or -h hidden files, and we display that output in /b bare format. Using the output from dir, we run find and specify to /v display all non-empty lines and then /c count the number - which becomes parameter %%B.
Finally, we set %%B as our counting variable (cnt) - if !cnt! is equal to 2, we see if the folder already exists in the new directory, and if it does not we robocopy it over. The move command was giving me some trouble because the folder would be locked by the loop, so if you want you could also throw in a DEL command to delete the original folder.
Let me know if that helps! Hopefully your research was going well anyway.
References: Counting Files, FOR Looping, pushd, DIR, FIND, robocopy

Batch Script Deleting Files Instead of Moving

I am still a beginner to batch scripting so I would appreciate more explanation than usual to help me if at all possible.
Purpose:
I wrote this script to try to move files based on whether they have a folder's name within their name. For example, I have a folder named "cow" and a file named "cow_5234.txt", the file would be moved into the folder. The purpose of this is to move files with company names to a company folder from a messy folder full of files so I don't think a file going to the wrong folder will be much of a problem.
Problem:
The problem I am having is that many of the files that are supposed to be transferred to folders are being misplaced. I have around 3000 files in a folder along with 300 folders and this script. After I run it, only around 100 files get placed into the correct folders, while 900 are left behind (because they don't have a folder name within them) while the rest just disappear.
What I have tried to do:
I have gone through and checked the original list of folder names, which is all correct. Then I modified the script to output the filename to a .txt file instead of move it. Instead of getting a reasonable amount of files, there are 4000 files (I checked the line count). Some of these files don't have a folder name in them. I then took a subset of around 200 files and 20 folders and ran the script with them. For some reason, only 80 files remained, 1 was placed into a folder, although it didn't have a single similar character as the folder, and the rest just disappeared. I'm not sure what is happening at all. Here is the code:
#echo off
dir /a:d /b > list.txt
for /F %%i in (list.txt) do call :process %%i
goto :eof
:process
set "search=%1"
for /f "eol=: delims=" %%F in ('dir /A:-D /b^|find "%search%"') do move /Y "%%F" "%search%"
goto :eof
Edit 1:
As recommended in the comments, I have added a "goto :eof" to the end of the block of code, however, the problem still remains.
Edit 2:
I didn't add a "goto :eof" to the end of the main function. Thanks for clarifying!

Batch substring for variable in loop [duplicate]

I have a number of files with the same naming scheme. As a sample, four files are called "num_001_001.txt", "num_002_001.txt", "num_002_002.txt", "num_002_003.txt"
The first set of numbers represents which "package" it's from, and the second set of numbers is simply used to distinguish them from one another. So in this example we have one file in package 001, and three files in package 002.
I am writing a windows vista batch command to take all of the files and move them into their own directories, where each directory represents a different package. So I want to move all the files for package 001 into directory "001" and all for 002 into directory "002"
I have successfully written a script that will iterate over all of the txt files and echo them. I have also written a scrip that will move one file into another location, as well as creating the directory if it doesn't exist.
Now I figure that I will need to use substrings, so I used the %var:~start,end% syntax to get them. As a test, I wrote this to verify that I can actually extract the substring and create a directory conditionally
#echo off
set temp=num_001_001.txt
NOT IF exist %temp:~0,7%\
mkdir %temp:~0,7%
And it works. Great.
So then I added the for loop to it.
#echo off
FOR /R %%X IN (*.txt) DO (
set temp=%%~nX
echo directory %temp:~0,7%
)
But this is my output:
directory num_002
directory num_002
directory num_002
directory num_002
What's wrong? Does vista not support re-assigning variables in each iteration?
The four files are in my directory, and one of them should create num_001. I put in different files with 003 004 005 and all of it was the last package's name. I'm guessing something's wrong with how I'm setting things.
I have different workarounds to get the job done but I'm baffled why such a simple concept wouldn't work.
Your problem is that the variable get replaced when the batch processor reads the for command, before it is executed.
Try this:
SET temp=Hello, world!
CALL yourbatchfile.bat
And you'll see Hello printed 5 times.
The solution is delayed expansion; you need to first enable it, and then use !temp! instead of %temp%:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R %%X IN (*.txt) DO (
set temp=%%~nX
echo directory !temp:~0,7!
)
See here for more details.
Another solution is to move the body of the for loop to a subroutine and call it.
#echo off
FOR /R %%X IN (*.txt) DO call :body %%X
goto :eof
:body
set temp=%~n1
echo directory %temp:~0,7%
goto :eof
Why do this? One reason is that the Windows command processor is greedy about parentheses, and the results may be surprising. I usually run into this when dereferencing variables that contain C:\Program Files (x86).
If the Windows command processor was less greedy, the following code would either print One (1) Two (2) or nothing at all:
#echo off
if "%1" == "yes" (
echo 1 (One)
echo 2 (Two)
)
However, that's not what it does. Either it prints 1 (One 2 (Two), which missing a ), or it prints 2 (Two). The command processor interprets the ) after One as the end of the if statement's body, treats the second echo as if it's outside the if statement, and ignores the final ).
I'm not sure whether this is officially documented, but you can simulate delayed expansion using the call statement:
#echo off
FOR /R %%X IN (*.txt) DO (
set temp=%%~nX
call echo directory %%temp:~0,7%%
)
Doubling the percent signs defers the variable substitution to the second evaluation. However, delayed expansion is much more straightforward.

Batch move files in folders to newly created folders

I want to move all files in some folders to a newly created folder in that same folder. For easier understanding, see the example below (the input is shown left, output is shown right):
C:\1\A\file1.tif C:\1\A\Named\file1.tif
file2.tif file2.tif
file3.tif ==> file3.tif
C:\1\B\file1.tif C:\1\B\Named\file1.tif
file2.tif file2.tif
file3.tif file3.tif
In the example above, I have only shown the first three files in every folder, but the total number may vary (usually there are 1000 files per folder). Also, I have only shown two folders (A and B), but the total number of folders may vary as well (usually about 10 folders). Finally, I have only shown the folder '1', but the number of these kind of folders may also vary (usually '1' through '10'). So I was looking to a script that could do these actions independent of the number of files or folders, and independent of the names of the folders/files (I chose '1', 'A' and 'file1.tif' only as examples).
The idea is that, now, I have to manually create empty folders (called 'Named' in the example above) in each folder ('A' and 'B' in the example above) where the files are. Then I have to manually move all the files into that newly created folder 'Named'. I have to do this for all folders (about 100). I can do this entire process manually if I had to do it only once, but the thing is that I have to do this process many times :-). So automating this would save a lot of time.
Does anyone know a script that can do this? Thanks a lot!
tested a little, this might work, in a command file
make a cmd file with these lines
for /r %%a in (*.*) do call :singlecopy %%a
goto :eof
:singlecopy
set src=%~p1
set dst=%~p1NAMED
set file=%~n1%~x1
rem replace NAMED in src with nothing
set srctst=%src:NAMED=%
rem if src and srctst are still the same, copy
if %srctst%==%src% robocopy %src% %dst% %file% /move /create
goto :eof
After thorough testing, this works great. However, as it is a lot of files, you may want to set up a little test environment, like in your example, to use this on first, before you use it on your actual data.
setlocal enabledelayedexpansion
cd C:\rootfolder
for /f "tokens=*" %%a in ('dir /s /b /a:d') do (
attrib "%%a\*.*" | find "File not found"
if !errorlevel!==1 (
if not exist "%%a\Named" md "%%a\Named"
xcopy "%%a\*.*" "%%a\Named"
del "%%a\*.*" /f /q
)
)

windows batch files: setting variable in for loop

I have a number of files with the same naming scheme. As a sample, four files are called "num_001_001.txt", "num_002_001.txt", "num_002_002.txt", "num_002_003.txt"
The first set of numbers represents which "package" it's from, and the second set of numbers is simply used to distinguish them from one another. So in this example we have one file in package 001, and three files in package 002.
I am writing a windows vista batch command to take all of the files and move them into their own directories, where each directory represents a different package. So I want to move all the files for package 001 into directory "001" and all for 002 into directory "002"
I have successfully written a script that will iterate over all of the txt files and echo them. I have also written a scrip that will move one file into another location, as well as creating the directory if it doesn't exist.
Now I figure that I will need to use substrings, so I used the %var:~start,end% syntax to get them. As a test, I wrote this to verify that I can actually extract the substring and create a directory conditionally
#echo off
set temp=num_001_001.txt
NOT IF exist %temp:~0,7%\
mkdir %temp:~0,7%
And it works. Great.
So then I added the for loop to it.
#echo off
FOR /R %%X IN (*.txt) DO (
set temp=%%~nX
echo directory %temp:~0,7%
)
But this is my output:
directory num_002
directory num_002
directory num_002
directory num_002
What's wrong? Does vista not support re-assigning variables in each iteration?
The four files are in my directory, and one of them should create num_001. I put in different files with 003 004 005 and all of it was the last package's name. I'm guessing something's wrong with how I'm setting things.
I have different workarounds to get the job done but I'm baffled why such a simple concept wouldn't work.
Your problem is that the variable get replaced when the batch processor reads the for command, before it is executed.
Try this:
SET temp=Hello, world!
CALL yourbatchfile.bat
And you'll see Hello printed 5 times.
The solution is delayed expansion; you need to first enable it, and then use !temp! instead of %temp%:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R %%X IN (*.txt) DO (
set temp=%%~nX
echo directory !temp:~0,7!
)
See here for more details.
Another solution is to move the body of the for loop to a subroutine and call it.
#echo off
FOR /R %%X IN (*.txt) DO call :body %%X
goto :eof
:body
set temp=%~n1
echo directory %temp:~0,7%
goto :eof
Why do this? One reason is that the Windows command processor is greedy about parentheses, and the results may be surprising. I usually run into this when dereferencing variables that contain C:\Program Files (x86).
If the Windows command processor was less greedy, the following code would either print One (1) Two (2) or nothing at all:
#echo off
if "%1" == "yes" (
echo 1 (One)
echo 2 (Two)
)
However, that's not what it does. Either it prints 1 (One 2 (Two), which missing a ), or it prints 2 (Two). The command processor interprets the ) after One as the end of the if statement's body, treats the second echo as if it's outside the if statement, and ignores the final ).
I'm not sure whether this is officially documented, but you can simulate delayed expansion using the call statement:
#echo off
FOR /R %%X IN (*.txt) DO (
set temp=%%~nX
call echo directory %%temp:~0,7%%
)
Doubling the percent signs defers the variable substitution to the second evaluation. However, delayed expansion is much more straightforward.

Resources