Batch file to create folder and move file in the folder - batch-file

I am in the middle of batch extracting screenshots for contents we are planning to use on a tube site I am working on.
The jpeg files per content is labled as followed:
6c82c0239f6eb839-1
6c82c0239f6eb839-2
all the way to 120
The file name is different per content
a82384e2c46ba4af-1
a82384e2c46ba4af-2
etc.
They will all be extracted to a singe folder.
So I basically need a batch file that will create folders based on the content name without the dash and number and move all 120 jpegs in the folder with the content name.
For example:
Create folder named 6c82c0239f6eb839 and
move 6c82c0239f6eb839-1 to 6c82c0239f6eb839-120 in to the created folder.
I saw another thread with the following batch file. its pretty much what I want but the folder name is only 3 characters long and the files are copied to the newly created folders instead of moving them.
#echo off
SetLocal EnableDelayedExpansion
for /F "delims=" %%a in ('dir /b *.jpeg') do (
set Name=%%a
set Folder=!Name:~0,3!
xcopy /y "%%a" !Folder!\
)
Could someone change this so that it will display full file name without the dash and number for the folders and move files in its respective folders instead of copy?
Thank you

#echo off
setlocal
#rem Get each jpeg file.
for /F "delims=" %%A in ('2^>nul dir /b *.jpeg') do (
rem Get filename as token before the dash.
for /f "delims=-" %%B in ("%%~A") do (
rem Make dir if needed.
if not exist "%%~B" md "%%~B"
rem Check if isdir.
2>nul pushd "%%~B" && popd
if errorlevel 1 (
>&2 echo Failed isdir "%%~B".
) else (
rem Do the move operation.
>nul move /y "%%~A" "%%~B"
if errorlevel 1 (
>&2 echo Failed move "%%~A" to "%%~B"
)
)
)
)
exit /b %errorlevel%
The code is well remarked so if you want to understand
the evaluated code by changing #echo off to #echo on.
The use of %errorlevel% after the exit /b is not
required though will let you know what the errorlevel is
when #echo on is used.
The pushd tests for a directory
(even if it is a symlink).
errorlevel is checked to decide if to echo a
error message or do the move.
As the for loop variables are used direct, use of
enabledelayedexpansion is not needed.
Many commands support the argument of /? to get help
about the command. i.e. move /?.

If you only try to copy the correct jpeg to the correct folder, you can do this:
#echo off
SetLocal EnableDelayedExpansion
CD <CORRECT ROOT PATH>
for /F "delims=" %%a in ('dir /b *.jpeg') do (
set Name=%%a
REM I presume all the files have 16 characters before the dash
set Folder=!Name:~0,16!
IF NOT EXIST !Folder! MKDIR !FOLDER!
xcopy /y "%%a" !Folder!\
)
I was not able to test.

First of all, I would like to apologize for my manners regarding my initial post.
The answer by micheal_heath has resolved my issue.
Furthermore, I happened to find this post by user Salmon Trout from a different site which also worked.
Batch file to make folders with part of file name and then copy files
#echo off
setlocal enabledelayedexpansion
for %%A in (*.psd *.jpg) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=_" %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! does not exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
I just changed the the following line remove the hypen and numbers to create folders for the file name properly.
for /f "tokens=1* delims=-***" %%D in ("!fname!") do set folname=%%D
I still lack the knowledge on why and how both methods work, but this has been an interesting start for me. I hope other beginners trying to solve a similar issue can find something useful from this post.

Related

Trying to get some script to move a pdf file into a folder based on first 4 characters of filename

I am trying to move a list of .pdf files to folders based on the first 4 characters of said pdf files
#echo off
setlocal enabledelayedexpansion
for %%A in (*.pdf) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=_" %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! does not exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
To move all .pdf files in the current directory into directories named using the first four characters of their basename, here's a batch-file example, (without all of the unnecessary screen output):
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For %%A In (*.pdf)Do (Set "fN=%%~nA"
SetLocal EnableDelayedExpansion
RoboCopy . "!fN:~,4!" "%%A" /Mov>NUL
EndLocal)
EndLocal
GoTo :EOF
You could probably even do it as a single line command.
From a batch-file:
#For %%A In (*.pdf)Do #Set "fN=%%~nA"&Call RoboCopy . "%%fN:~,4%%" "%%A" /Mov>NUL
From a single cmd instance:
For %A In (*.pdf)Do #Set "fN=%~nA"&Call RoboCopy . "%fN:~,4%" "%A" /Mov>NUL
Please note that the ideas presented above assume that your .pdf basenames do not contain any exclamation marks/points and that Robocopy.exe exists in the current directory or within the locations specified under %PATH%.
Please also note that the 4th character in your basenames should not be a space or period, as the Windows shell and user interface does not support those.

Creating List of Folders from File Names

I have a folder containing many files named as such: JBMA_23456.docx, JMRI_21456.docx, CM_22554.docx, QUA_11224.docx. How do I create a sub-folder for each file bearing the same name as the file but without the .docx file extension? Additionally, I want to store the filename only as variables.
For example, I need to create a sub-folder named JBMA_23456 from the document
JBMA_23456.docx. Can anyone point me in teh right direction?
#echo off
for %%A in (*.docx) do if not exist "%%~nA" md "%%~nA"
This creates a folder with the same name as each .docx file.
View modifiers in for /? or in call /?. The n modifier is the name.
Path modifiers:
dpnx is drive, path, name and extension.
Here's an example batch file which attempts to perform the tasks as laid out in your question:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "BaseDir=C:\Users\Compo\Desktop\test"
Set "FileExt=.docx"
For /F "Delims==" %%A In ('Set var[ 2^>Nul') Do Set "%%A="
Set "i=0"
For /F "Delims=" %%A In ('Where "%BaseDir%":*%FileExt% 2^>Nul') Do (Set /A i+=1
Call Set "var[%%i%%]=%%~nA"
If Exist "%%~dpA%%~nA\" (Echo Sub-Folder %%~nA already exists in %BaseDir%
) Else (Set /P "=Creating sub-folder %%~nA in %BaseDir%"<Nul
MD "%%~dpA%%~nA">Nul 2>&1 && (Echo= was successful) || Echo= failed))
Set var[ 2>Nul
Pause
In order to use it, you would first ensure that the directory holding your files, (excluding any trailing backslash), is placed between the = and " on line 4, and the single file extension, (including the leading period, .), similarly on line 5.
It is not entirely clear what you are asking for...
Anyway, here is the code i made
echo off
chcp 65001
cls
for /f "usebackq delims=." %%0 in (`dir /b "*.docx"`) do (
set filename=%%0
md %filename%
)
cmd /k
It creates a new folder for every file. Feel free to ask if this was not what you expected

Batch script that will insert filenames into files within multiple subfolders

I need help creating a batch script that will add the filename to the first line of every .csv within all subfolders. The batch file will be in the mainfolder. The same folder will contain several subfolders, each containing a large amount of .csv files. I need the files to stay within their respective folders. My goal is to add this to another working script I have that merges all files within a subfolder into a single .csv. This will provide a way to navigate through the merged file. I found some similar posts, but they weren't quite what I was looking for. This is the closest thing I could find but the delimiter stuff is throwing me off Batch file to Write Filename to first line
File Structure Example:
C:\MainFolder\batch_script.bat
C:\MainFolder\SubFolder1\csv1.csv
C:\MainFolder\SubFolder1\csv2.csv
C:\MainFolder\SubFolder2\csv3.csv
C:\MainFolder\SubFolder2\csv4.csv
File Contents before running script
csv1.csv:
This is the content of csv1.csv
csv2.csv:
This is the content of csv2.csv
csv3.csv:
This is the content of csv3.csv
csv4.csv:
This is the content of csv4.csv
File Contents after running script:
csv1.csv:
csv1.csv
This is the content of csv1.csv
csv2.csv:
csv2.csv
This is the content of csv2.csv
csv3.csv:
csv3.csv
This is the content of csv3.csv
csv4.csv:
csv4.csv
This is the content of csv4.csv
P.S.
I also found this code on another website but I'm not sure how I would make it loop through the different subfolders
FOR /F "usebackq tokens=1" %%i IN (`DIR /B`) DO (
ECHO %%i >> %1
TYPE %%i >> %1
)
#echo off
setlocal enableextensions disabledelayedexpansion
for /r %%a in (*.csv) do (
set /p "firstLine=" < "%%~fa"
setlocal enabledelayedexpansion
for /f "delims=" %%b in (".!firstLine!") do endlocal & if not "%%~b"==".%%~nxa" (
( echo %%~nxa
type "%%~fa"
) > "%%~fa.new"
move /y "%%~fa.new" "%%~fa" >nul
)
)
What it does is generate a new file with the name of the csv as the first line, appends the csv to the new file and moves the new file over the csv. In the process, it tests if the content of the first line is the same as the name of the csv to avoid reinclusion of the filename on each run of the batch file.
edited to adapt to comments - As the process will not be run more than once for set of csv files, the full code can be reduced to
#echo off
setlocal enableextensions disabledelayedexpansion
for /r %%a in (*.csv) do (
( echo %%~nxa
type "%%~fa"
) > "%%~fa.new"
move /y "%%~fa.new" "%%~fa" >nul
)
Try this:
for /r %%a in (*.csv) do (
copy /y "%%~a" "%temp%\%%~na"
Echo %%~na > "%%~a"
for /f "usebackq" %%b in ("%temp%\%%~na") do Echo %%b >> "%%~a"
del "%temp%\%%~na"
)
And that should do what you want it to. I would test it out first if you could.
This should create an all.csv in every folder in the tree under the C:\MainFolder and add the filename before the contents of each CSV file.
The filename will contain the full path but that can easily be changed if needed.
#echo off
for /d /r "C:\MainFolder\" %%a in (*) do (
pushd "%%a"
(for %%b in (*.csv) do (
echo %%b
type "%%b"
)
)>all.tmp
ren all.tmp all.csv
popd
)
pause

create folders based on string in file name

I need a batch file to create a process for a list of files in a directory.
The filename structure is, for example: 00000_AAA_132144_2012021.txt
I need the batch to:
1 - Create a folder name based on the numbers after the second underscore, as this is the only constant in the naming.
2 - Move the file into the new folder.
In the example of the above the batch would create a folder called 132144 and then move the file 00000_AAA_132144_2012021.txt into the folder
For a similar requirement I used the script Endoro created for me (below). Is it possible to modify this to meet my requirement?
#echo off &setlocal
for /f "delims=" %%i in ('dir /b /a-d *.PDF') do (
set "filename1=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename1:~11,6!"
mkdir "!folder1!" 2>nul
move "!filename1!" "!folder1!"
endlocal
)
If you know that the filenames will be the same length, you can do the following to get the numbers after the second underscore -
set filename=00000_AAA_132144_2012021.txt
set dirname=%filename:~10,6%
If the spacing may vary - you can do the following -
for /f "delims=_ tokens=3" %%a in ('echo %filename%') do set dirname=%%a
And yes, the script written for you seems to do essentially the same thing as what you're asking - I've edited it to do what you've asked -
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir /b /a-d *.txt') do (
set "filename=%%~i"
for /f "delims=_ tokens=3" %%a in ('echo !filename!') do set folder=%%a
mkdir "!folder!" 2>nul
move "!filename!" "!folder!"
)
This will move all *.txt documents to a folder created based on the third section of the text files name. Note that this will cause problems if you have .txt documents in the directory that do not follow the same naming standard.
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "destdir=c:\destdir"
FOR /f "delims=" %%a IN ('dir /b /a-d "%sourcedir%\*_*_*_*.txt" ') DO (
FOR /f "tokens=3delims=_" %%m IN ("%%a") DO (
ECHO MD "%destdir%\%%m"
ECHO MOVE "%sourcedir%\%%a" "%destdir%\%%m\"
)
)
GOTO :EOF
Endoro's routine selects .pdf files, you've specified .txt
Find filenames matching the mask, find the third _-separated token in the name, make that directory and then move the file.
The required commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MD to MD to actually create the directories and change ECHO MOVE to MOVE to actually move the files.
Append 2>nul to suppress error messages (eg. when the directory already exists)
Append >nul to suppress report messages (eg. 1 file moved)

Create folder based on group of files

I have files with varying names...
Tim-01.jpg
Tim-02.jpg
Tim-03.jpg
jack-01.jpg
jack-02.jpg
jack-03.jpg etc in a single folder
I want to move all tim files into Tim folder and jack files to Jack folder etc.
Can it be done using .bat files ? If yes, please share the code for it.
Thank You.
#echo off
setlocal
set sourcedir=c:\sourcedir
for /f "tokens=1*delims=-" %%a in ('dir /b /a-d "%sourcedir%\*-*.*") do (
md "%sourcedir%\%%a" 2>nul
echo move "%sourcedir\%%a-%%b" "%sourcedir%\%%a\"
)
Note that the 2>nul suppresses error messages created when an attempt is made to recreate an existing directory
The MOVE is merely ECHOed. Remove the ECHO keyword to activae the move. It may also be prudent to append >nul to the MOVE statement to suppress the "1 file(s) moved" message.
As you may know, there are no arrays in Batch. So let's just use one.
#ECHO OFF &SETLOCAL
for /f "tokens=1*delims=-" %%a in ('dir /b /a-d *-*.jpg') do set "$%%a=%%a"
for /f "tokens=1*delims==" %%a in ('set $') do robocopy "%cd%" "%cd%\%%b" "%%b*" /mov /l
Remove /l from robocopy to make it working.
EDIT - Changed code to reduce the number of file moves. Now, all files with the same prefix get moved in one command.
#echo off
setlocal enableextensions
rem source of images
set "_dir=."
rem for each jpg with a dash in its name
for %%f in ("%_dir%\*-*.jpg") do (
rem if the file still exists (maybe it has been moved)
rem then split the file name with the dash as delimiter
if exist "%%~ff" for /F "tokens=1 delims=-" %%s in ("%%~nf") do (
rem and if we get a folder target, move the all the files
rem with same prefix to proper folder
if not "%%~s"=="" (
robocopy "%_dir%" "%_dir%\%%~s" "%%~s-*.jpg" /mov /njs /njh
)
)
)
endlocal
EDIT2 - Changed to adapt to comments
#echo off
setlocal enableextensions enabledelayedexpansion
rem source of images
set "_dir=."
rem for each jpg with a dash in its name
for %%f in ("%_dir%\*-??.jpg") do (
rem if the file still exists (maybe it has been moved)
if exist "%%~ff" (
rem get the filename without the 3 last characters
set "_target=%%~nf"
set "_target=!_target:~0,-3!"
rem and if we get a folder target, move the all the files
rem with same prefix to proper folder
if not "!_target!"=="" (
robocopy "%_dir%" "%_dir%\!_target!" "!_target!-??.jpg" /mov /njs /njh
)
)
)
endlocal

Resources