Using batch files to remove a single number from a folder name - batch-file

At work we use a bespoke program to search through a directory tree and find an individual image file. These files are stored in folders that have a 7-digit name, starting with '18' - so for instance '1873456', '1873457', '1873458' etc. The problem I have is at some point last year the procedure that creates these folders and populates the images in them reached '1899999' - and then rolled over to '18100000' and carried on like that for over 4,000 folders before it was caught and corrected.
The bespoke program we use can only handle seven-digit folder names. What I would like to do is create a batch file that renames all the eight-digit folders by removing the extra '1' in the name, so '18100000' becomes '1800000' and so forth until '18104013' becomes '1804013'.
Can anyone help?

Run this in the base folder, it will not change any folders.
A file called renfile.bat.txt will be created that contains the rename command for the folders that match the filespec. Examine it in notepad to see if it is ok and then rename it to renfile.bat and run it.
It's not tested.
#echo off
setlocal enabledelayedexpansion
for /d /r %%a in (18??????) do (
set "name=%%~nxa"
>>renfile.bat.txt echo ren "%%a" "!name:~0,2!!name:~3!"
)

Something like
for /l %%x in (100000,1,104013) do (
set oldsuffix=%%x
set newsuffix=%oldsuffix:~-5%
ren 18%%x 18%newsuffix%
)

setlocal enableextensions enabledelayedexpansion
for /d /r "c:\somewhere" %%f in (181?????) do (
set "name=0" & set /a "name+=%%~nf" 2>nul
if !name! gtr 1899999 ren "%%~ff" "18!name:~-5!"
)

Related

How to batch transfer rename?

There are two folders holding equal amounts of files between them.
I'd like to apply the names from one set ; to the other set of files in no particular order. Inherit the name, but retain the extension .
Input files are .bmp Output files are .ini ( has a gear symbol ).
Example :
folder 1- Flowers.bmp ; folder 2- blank.ini
. To this:
folder 1- Flowers.bmp ; folder 2- Flowers.ini
There would be more files , but equal .
The .ini files are all copies . So they may have a generic name and numbered if that matters to know . Those would all receive one name each from the other .bmp files in the other folder.
Normally I have both folders situated on the Desktop .
I make sure both folders have equal number of files between them . That would be a constant .
I'm trying to stream line some menial repetitive daily tasks .
I did search and what I have found does not really help.
#ECHO OFF
SET "vers=%~1"
IF "%vers%" == "" SET /P "vers=Enter Vers: "
FOR %%F IN (file_XX_*.*) DO CALL :process "%%F"
GOTO :EOF
:process
SET "name=%~nx1"
SETLOCAL ENABLEDELAYEDEXPANSION
SET "name=!name:_XX_=_%vers%_!"
RENAME %1 "%name%"
ENDLOCAL
Hoping to find a solution to this finally .
Ok, here is a slightly long version, but it makes sure it gets the content of each folder.
Note You must ensure that the path to both folders are correctly specified in the third and fourth line:
#echo off
setlocal enabledelayedexpansion
set "source=%userprofile%\Desktop\folder 1"
set "destination=%userprofile%\Desktop\folder 2"
set /a num=0
for %%a in ("%source%\*") do (
set /a num+=1
set "fr!num!m=%%~na"
)
set /a oldn=!num!
set /a num=0
for %%b in ("%destination%\*") do (
set /a num+=1
set "to!num!r!=%%~nxb"
set "ext=%%~xb"
)
pushd "%destination%"
for /l %%i in (1,1,!oldn!) do ren "!to%%ir!" "!fr%%im!%ext%"
popd
pause
You can remove pause at the bottom of the script, once you are happy with the output.
This is not the most effective way, but considering your limited batch experience, I guess an understandable approach is better than an optimized one (using array-like variables).
#echo off
setlocal enabledelayedexpansion
(for %%A in ("folder 1\*.bmp") do echo %%~nA)> "%temp%\names.txt"
<"%temp%\names.txt" (
for %%A in ("folder 2\*.ini") do (
set /p "name="
ECHO ren "%%A" "!name!.ini"
))
The first for loop creates a list of the desired names (from Folder 1). The modifier %%~nA returns the name only.
The second for processes each file in Folder 2 and takes a name from the previously generated file for each file. This depends on the fact that the number of files in both folders are the same, else you may get undesired results.
I disabled the actual ren command by just echoing it. Check the output and only when you are satisfied, remove the ECHO.

how to bookmark and delete the line for multiple files

I want to book mark and delete the lines from the multiple XML files. I'm new to batch file programming. Could any one pls help me to create the batch file which should read the file and delete the line which contains the string.
Eg: Below is the content of one XML file in which i want to delete the lines which contains "cimage.gif" and "appcover".
<file>/cimages/ncomms_cimage.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/abs/ncomms6646.html</file>
<file>/ncomms/2014/141223/ncomms6646/carousel/ncomms6646-f1.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/carousel/ncomms6646-f2.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/carousel/ncomms6646-f3.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/carousel/ncomms6646-f4.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/carousel/ncomms6646-f5.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/carousel/ncomms6646-f6.jpg</file>
<file>/ncomms/2014/141223/ncomms6646/compound/ncomms6646_ci.html</file>
<file>/ncomms/2014/141223/ncomms6646/covers/appcover-ncomms-v5-ncomms6646-150x193.png</file>
<file>/ncomms/2014/141223/ncomms6646/covers/appcover-ncomms-v5-ncomms6646-450x579.png</file>
<file>/ncomms/2014/141223/ncomms6646/covers/appcover-ncomms-v5-ncomms6646-75x100.png</file>
<file>/ncomms/2014/141223/ncomms6646/extref/ncomms6646-s1.pdf</file>
<file>/ncomms/2014/141223/ncomms6646/extref/ncomms6646-s2.xls</file>
<file>/ncomms/2014/141223/ncomms6646/extref/ncomms6646-s3.xls</file>
<file>/ncomms/2014/141223/ncomms6646/extref/ncomms6646-s4.avi</file>
<file>/ncomms/2014/141223/ncomms6646/fig_tab/ncomms6646_F1.html</file>
<file>/ncomms/2014/141223/ncomms6646/fig_tab/ncomms6646_F2.html</file>
<file>/ncomms/2014/141223/ncomms6646/fig_tab/ncomms6646_F3.html</file>
<file>/ncomms/2014/141223/ncomms6646/fig_tab/ncomms6646_F4.html</file>
<file>/ncomms/2014/141223/ncomms6646/fig_tab/ncomms6646_F5.html</file>
I want to delete both line which contains "appcover" and "cimage"
Coudld you pls update the code n give me? Sorry since Iam new to batch file i'm depending on your coding only.
Also If i want to edit the 10 files i cant put all xmls in one folder since the filename of the all xmls will be pushlive-manifest.xml only, all these files are stored in a their own diretories. Is any way to put this batch file in route folder adn it should read the xmls in the sub-directories with in the root folder.
Eg: route dir path is:D:/abc the xmls are in "D:/abc/123", "D:/abc/121" "D:/abc/125" and so on.
So i can place the batch file in D:/abc folder and if i run batch file it should read the xmls wch are there in "D:/abc/123", "D:/abc/121" "D:/abc/125" and so on.
Expecting your reply on this!
I changed the coding as below:
#ECHO OFF
SETLOCAL
SET "sourcedir=D:\test"
FOR /r "%sourcedir%" %%a IN (pushlive-manifest*.xml) DO (
FINDSTR /v /L "cimage.jpg appcover" "%%a" >"%%~dpna.txt"
move /y "%%a" "%%~na"
)
GOTO :EOF
and as a result it is not processinfg other xmls but it just creates one txt for each xml in its dir. and the out file is not overwiting the original xml it is still generating txt file. this time it is not creating copy of input xml to txt file where as as it is deleting the expecte dlines in the xml and converting it into txt. PLs suggest
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
FOR %%a IN ("%sourcedir%\*.xml") DO (
FINDSTR /v /L "cimage.gif appcover" "%%a" >"%%~dpna.txt"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
A new file is generated called samebasename.txt in the same directory as the directory scanned. It's not clear whether you want to delete lines that contain either "cimage.gif" **OR** "appcover" or those that contain both "cimage.gif" and "appcover". This code assumes the former.
Revision for revise requirement : search for .xmls in tree
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /r "%sourcedir%" %%a IN (*.xml) DO (
FINDSTR /v /L "cimage.gif appcover" "%%a" >"%%~dpna.txt"
)
GOTO :EOF
Note that in the Windows world, \ is a directory-separator and / is a switch-indicator. Windows often, but not always, makes the translation. Best to use the correct form.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /r "%sourcedir%" %%a IN (pushlive-manifest*.xml) DO (
FINDSTR /v /L "cimage.gif appcover" "%%a" >"%%~dpna.LMX"
Move /y "%%~dpna.LMX" "%%~nxa"
)
GOTO :EOF
This should work for you - just change the directory-name as required

How to use batch job to add the file "create date" into all the files in a directory?

I have a folder that gets a new file added everyday to the folder with the same file name but incremental extension such as .001, .002, .003, etc. However, if there's no file within the folder it starts at .001 again.
The problem is they are all named the same and if I move them to another folder to archive them it would just overwrite the same file over and over again. I could create a folder each day with the date with only one file in it, but that seems a bit redundant.
Is there a way to look at the create date of each file and rename it to the create date?
I've gotten this far, but it looks like for this situation I have to use a static file name, how to loop through the entire directory?
SET filename = C:\test.001
FOR %%f IN (%filename%) DO SET filedatetime=%%~tf
rename c:\test.001 C:\test_%filedatetime%.txt
move C:\*.txt C:\archive\
this provides the correct sort order:
#echo off &setlocal disableDelayedExpansion
set "startfolder=%userprofile%\test"
cd /d "%startfolder%"
for %%a in (*) do (
for /f "delims=." %%b in ('wmic datafile where "name='%startfolder:\=\\%\\%%~a'" get lastmodified^|find "."') do (
echo(ren "%startfolder%\%%~a" "%%~b.txt"
)
)
Remove echo to get it working.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "targetdir=c:\sourcedir"
SET "destdir=c:\destdir"
PUSHD "%targetdir%"
FOR %%a IN (*.*) DO (
SET "timestamp=%%~ta"
SET "timestamp=!timestamp:/=_!
SET "timestamp=!timestamp::=_!
SET "timestamp=!timestamp:.=_!
SET "timestamp=!timestamp:,=_!
SET "timestamp=!timestamp: =_!
ECHO MOVE "%%a" "%destdir%\%%~na.!timestamp!"
)
GOTO :EOF
This should work with any file in the nominated target directory where the name does not include ! or ^.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
The gymnastics around timestamp are intende to replace /: with _ since these are illegal filename characters. Space., are similarly replaced - they're legal but often painful.
If you want the destination filename to be name.003.timestamp, remove the ~na from the destination name.
Try like this :
SET $path=The_path_who_contain_the_FILES
FOR /F "DELIMS=" %%f IN ('dir "%$path%" /a-d/b') DO (
SET filedatetime=%%~tf
move "%%~dpnxf" "C:\archive\test_%filedatetime%.txt")

How to make a batch script to create a folder from only numbers in file names

I am trying to create a batch script on windows 7 to do the following:
I have a folder which another program dumps files to.
All the files have numbers in their name along with other identifying information.
I would like to have a batch script search for all the digits in the file name and then create a folder (folder name is just the digits) and move all files that contain those digits to the folder.
It must be applicable to numerous users in my office.
currently i have a very bad primitive system running which doesn't account for mistakes:
#echo off
setlocal enabledelayedexpansion
pushd "%USERPROFILE%\Desktop\RawFiles"
for %%a in (*) do (
set fldr=%%~na
set fldr=!fldr:~0,5!
md "!fldr!"
move "%%a" "!fldr!"
)
popd
if not exist "%USERPROFILE%\Dropbox\agents" mkdir "%USERPROFILE%\Dropbox\agents"
SET "src_folder=%USERPROFILE%\Desktop\RawFiles"
SET "tar_folder=%USERPROFILE%\Dropbox\agents"
for /f %%a IN ('dir "%src_folder%" /b') do move /-y %src_folder%\%%a %tar_folder%
exit
the files in the "rawfiles" folder are as follows:
12345 - tech pack.pdf
12345.pdf
12345-artwork.AI
"#12345- artwork.AI"
What i created only works for perfect instances where the numbers come first in files and are exactly 5.
Unfortunately there is a lot of human error here so this solution is not viable.
an example of a mistake is an accidental 6 digit number or even putting the "#" sign before the numbers
I also would like to be able to override the files in the destination folder by running this twice but am getting "access denied".
Please help!
thanks
The Batch file below extract the digits from the file names as requested (maximum 6 groups of digits separated by other characters, this may be modified), so you may manipulate they in any way you wish; the ECHO commands are just examples. Note that the space must be the last character in eliminate variable.
#echo off
setlocal EnableDelayedExpansion
set "eliminate=#-abcdefghijklmnopqrstuvwxyz "
for %%a in (*.*) do (
for /F "tokens=1-6 delims=%eliminate%" %%b in ("%%~Na") do set folder=%%b%%c%%d%%e%%f%%g
if not exist "!folder!" ECHO md "!folder!"
ECHO move "%%a" "!folder!"
)

Batch Script to create folder based on name, add to existing code

The code below works fine, here is a list of it's functions:
It moves files based on the fist 4 characters to a pre-created folder with the same first 4 characters
If the folder does not exist, it will not move the file, as there is no folder with the same fist 4 chars.
#echo on
setlocal enabledelayedexpansion
cls
pushd R:\Contracts\Sites
for /f "tokens=*" %%1 in ('dir /a-d /b *') do (
set filename=%%1&set dirname=!filename:~0,4!
for /f "tokens=*" %%A in ('dir /ad /b') do (
set dirid=%%A & set dirid=!dirid:~0,4!
if "!dirid!" equ "!dirname!" move %%1 %%A
)
)
I would like to add one extra function to this code please. Pleas have a look at the example below.
I have 5 files
X32A-test.docx or X32A-test.pptx (there will only be one docx or pptx, "NEVER two with the same name")
X32A-test.pdf
X32A-test.avi
X32A-test-eng.sub
X32A-test-small.jpg
I would like the code to CREATE a folder if it does not exist, based on the file name if it has the extension docx or pptx.
So with the above example it would create a folder named: "X32A-test". Then all the other files with "X32A" in the front of the name will be moved to that newly created folder "X32A-test".
I hope it is clear enough. If not please ask me for more information.
Thank you
It is much simpler and more efficient to use the simple FOR instead of FOR /F in your case.
And rather than looping through every file and moving them individually, it is easier and more efficient to use wildcards.
The first loop finds the .pptx and .docx files and creates folders as needed
The second loop finds all the directories and moves all files that start with the directory name into the directory.
#echo on
setlocal enableDelayedExpansion
cls
pushd R:\Contracts\Sites
for %%F in (*.docx *.pptx) do (
set "folder=%%F"
2>nul md !folder:~0,4!
)
for /d %%F in (*) do move %%F* %%F
popd
If needed, you can protect yourself against directory names shorter than length 4.
#echo on
setlocal enableDelayedExpansion
cls
pushd R:\Contracts\Sites
for %%F in (*.docx *.pptx) do (
set "folder=%%F"
set folder=!folder:~0,4!
if !folder:~0,3! neq !folder! 2>nul md !folder!
)
for /d %%F in (????) do (
set "folder=%%F"
if "!folder:~0,3!" neq "%%F" move %%F* %%F
)
popd
Note that this solution may fail if a file name contains !. If that arises then you need to toggle delayed expansion on and off within the loop(s).
I can see the entire process (including the part already implemented) like this:
All the files that are not yet in their "home" directories are moved there.
For all .docx and .pptx files left, create directories based on the files' names.
Obviously, the step #2 creates new "homes" and those will still be "uninhabited" this far. So all that is left to do now is to repeat the step #1.
So I would probably reorganised your process and, with the additional requirement, it could be implemented this way:
…
PUSHD your_root_directory
FOR /D %%D IN (*) DO (
CALL :movefiles "%%D"
)
FOR %%F in (*.docx *.pptx) DO (
MKDIR "%%~dpnF"
CALL :movefiles "%%~dpnF"
)
…
GOTO :EOF
:movefiles
SET "dirname=%~n1"
SET "mask=%dirname:~0,4%*"
MOVE "%~dp1%mask%" %1
Note: The steps #2 and #3 could be either implemented as separate loops or combined in one. The above script uses the latter approach.
You can use negative offsets in the !var:~offset,len! evaluation as follows:
set fspec=X32A-test.docx
echo !fspec:~-10!
echo !fspec:~0,-10!
That second line above gives you -test.docx and you can simply check that against your two desired possibilities with an if statement (or two).
Then you can use the third line to get the rest of the name for creating a directory.
The following example script shows how this could be done:
#setlocal enableextensions enabledelayedexpansion
#echo off
set fspec=X32A-test.docx
set bit1=!fspec:~-10!
set bit2=!fspec:~0,-10!
if .!bit1!.==.-test.docx. echo mkdir !bit2!
if .!bit1!.==.-test.pptx. echo mkdir !bit2!
endlocal
I'm echoing the mkdir command rather than executing it so you need to take out the echo. You'll also need to integrate the set and if statements into your loop but, based on what you have so far, you should have little trouble with that.
If, as you seem to indicate in a comment, the first four characters are the key and the last five decide on whether to make the directory, as in:
x32s-test.docx
a21w-production.pptx
xxxx-whatever_the_blazes_you_want.some_other_rubbish.docx
Then you're really only interested in the first four and last five:
#setlocal enableextensions enabledelayedexpansion
#echo off
set fspec=a12b-whatever_the_blazes_you_want.some_other_rubbish.docx
set bit1=!fspec:~-5!
set bit2=!fspec:~0,4!
if .!bit1!.==..docx. echo mkdir !bit2!
if .!bit1!.==..pptx. echo mkdir !bit2!
endlocal
This checks the correct extensions and outputs:
mkdir a12b
as expected.

Resources