Move files into folders in batches of five? - windows

Suppose I have 50 files sorted by name.. I would like to create a batch script which gives me the following result:
Files 1 through 5 -> 01-05
Files 6 through 10 -> 06-10
and so on..How can I create a batch script to achieve this?
Note that 01-05 and 06-10 are directory names..
EDIT: Details
For eg. Consider this:
Source Directory:
101.mp4
102.mp4
103.mp4
104.mp4
and so on..
I want a resulting directory structure like this:
Destination Directory:
101-105:
101.mp4
102.mp4
103.mp4
104.mp4
105.mp4
106-110:
106.mp4
107.mp4
108.mp4
109.mp4
110.mp4
and so on..

This is what you want, change fileCount to change the file number in each subdirectory:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set fileCount=5
set filesNow=0
set nameStart=000
set nameEnd=000
FOR /F "usebackq delims=" %%i IN (`dir /b /O:N *.mp4`) do (
set /a filesNow+=1
set /a tmpValue=filesNow %% fileCount
::echo !filesNow!
::echo !fileCount!
::echo %%i
::echo !tmpValue!
if "!tmpValue!"=="1" (
set "nameStart=%%~ni"
mkdir _tmpDir_
)
move %%~nxi _tmpDir_\
if "!tmpValue!"=="0" (
rename _tmpDir_ !nameStart!-%%~ni
)
set "nameEnd=%%~ni"
)
if exist _tmpDir_ rename _tmpDir_ %nameStart%-%nameEnd%
You need to put them inside a bat/cmd file to work.
filesNow is for file number count.
Basically it's create a tmp folder and move files inside,
When files inside it reach the number, change the folder's name.
Several testing echo command I didn't remove, just used :: to comment them out, you can remove the :: to test them again.

Related

Create Folders and Relocate Files Based on Partial Filename

I have a series of photos in a folder with name format similar to this:
BA-ML-6256_Gocchup1.jpg
BA-ML-6256_Gocchup2.jpg
BA-ML-17302_Gocchup1.jpg
BA-ML-17302_Gocchup2.jpg
I want to create new folders like below that contain the files:
BA-ML-6256
BA-ML-17302
I tried using this script:
#echo off
for %%i in (*) do (
if not "%%~ni" == "organize" (
md "%%~ni" && move "%%~i" "%%~ni"
)
)
but it created these 4 folders instead:
BA-ML-6256_Gocchup1
BA-ML-6256_Gocchup2
BA-ML-17302_Gocchup1
BA-ML-17302_Gocchup2
Please help me create a batch script that would make this work.
#ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
FOR /f "tokens=1*delims=_" %%b IN ('dir /b /a-d "%sourcedir%\*_*.jpg"') DO (
ECHO MD "%sourcedir%\%%b"
ECHO MOVE "%sourcedir%\%%b_%%c" "%sourcedir%\%%b"
)
GOTO :eof
Always verify against a test directory before applying to real data.
The required MD 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. Append 2>nul to suppress error messages (eg. when the directory already exists)
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)
Naturally, you could remove the %sourcedir%\ throughout if you want to process the current directory.
The dir command lists the filenames only in the directory, and then only those that match *_*.jpg, that is anything1_anything2.jpg
The for /f assigns anything1 to %%b and anything2.jpg to %%c, using the _ as a delimiter (see for /? from the prompt, or thousands of items on SO for examples/documentation)
Then make the directory and move the file.
Simples!
You need to parse the file names to derive the target folder name.
Sample Batch File
The following batch file should do as you desire:
#echo off
for %%i in (*.jpg) do (
for /f "delims=_" %%j in (%%i) do (
md %%j
move "%%~i" "%%j"
)
)
)
This splits the file name at the "_" character to derive the target folder
Example Output
I started with this folder layout:
F:\projects\sx\batch>tree /f
Folder PATH listing
Volume serial number is 9C33-6BBD
F:.
create-test-data.cmd
md-and-move.cmd
BA-ML-6256_Gocchup1.jpg
BA-ML-6256_Gocchup2.jpg
BA-ML-17302_Gocchup1.jpg
BA-ML-17302_Gocchup2.jpg
No subfolders exist
Running the batch file gives this output:
F:\projects\sx\batch>md-and-move.cmd
1 file(s) moved.
A subdirectory or file BA-ML-6256 already exists.
1 file(s) moved.
1 file(s) moved.
A subdirectory or file BA-ML-17302 already exists.
1 file(s) moved.
and results in this folder layout:
F:\projects\sx\batch>tree /f
Folder PATH listing
Volume serial number is 9C33-6BBD
F:.
│ create-test-data.cmd
│ md-and-move.cmd
│
├───BA-ML-6256
│ BA-ML-6256_Gocchup1.jpg
│ BA-ML-6256_Gocchup2.jpg
│
└───BA-ML-17302
BA-ML-17302_Gocchup1.jpg
BA-ML-17302_Gocchup2.jpg

Loop through files in a folder and check if they have different extensions

I have a folder that contains files; each document should have .pdf and .xml format. I need to write a BAT file to run from a scheduled task to verify that both documents exist for each.
My logic is:
loop through files in the folder
strip each file to its name without extension
check that same name files exist for both .xml and pdf.
if not mark a flag variable as problem
when done, if the flag variable is marked, send an Email notification
I know how to use blat to sending email, but I'm having trouble to execute the loop. I found a way to get path and file name without extension but can't merge them.
I've used batch files a few time, before but I'm far from an expert. What am I missing?
Here's the code I have so far:
set "FolderPath=E:\TestBat\Test\"
echo %FolderPath%
for %%f in (%FolderPath%*) do (
set /p val=<%%f
For %%A in ("%%f") do (
Set Folder=%%~dpA
Set Name=%%~nxA
)
echo Folder is: %Folder%
echo Name is: %Name%
if NOT EXIST %FolderPath%%name%.xml
set flag=MISSING
if NOT EXIST %FolderPath%%name%.pdf
set flag=MISSING
)
echo %Flag%
pause
There is no need for fancy code for a task such as this:
#Echo Off
Set "FolderPath=E:\TestBat\Test"
If /I Not "%CD%"=="%FolderPath%" PushD "%FolderPath%" 2>Nul||Exit/B
Set "flag="
For %%A In (*.pdf *.xml) Do (
If /I "%%~xA"==".pdf" (If Not Exist "%%~nA.xml" Set "flag=MISSING")
If /I "%%~xA"==".xml" (If Not Exist "%%~nA.pdf" Set "flag=MISSING")
)
If Defined flag Echo=%flag%
Timeout -1
Something like this :
set "FolderPath=E:\TestBat\Test\"
pushd "%FolderPath%"
for %%a in (*.xml) do (
if exist "%%~na.pdf"(
echo ok
) else (
rem do what you want here
echo Missing
)
)
popd
Is this what you want?
#echo off
setlocal enabledelayedexpansion
set "FolderPath=E:\TestBat\Test\"
echo !FolderPath!
for /f "usebackq delims=" %%f in (`dir !FolderPath! /B`) do (
set /p val=<%%f
For %%A in ("%%f") do (
Set Folder=%%~dpA
Set name=%%~nxA
)
echo Folder is: !Folder!
echo Name is: !name!
if NOT EXIST !FolderPath!!name!.xml set flag=MISSING
if NOT EXIST !FolderPath!!name!.pdf set flag=MISSING
)
echo Flag: !flag!
pause
endlocal
You should reformat your code and keep in mind that the grama for batch file is critical. BTW, if you are trying to update the existing batch variable and read it later, you should enable localdelayedexpansion and use ! instead of %.
Keep it simple:
#echo off
pushd "E:\TestBat\Test" || exit /B 1
for %%F in ("*.pdf") do if not exist "%%~nF.xml" echo %%~nxF
for %%F in ("*.xml") do if not exist "%%~nF.pdf" echo %%~nxF
popd
This returns all files that appear orphaned, that is, where the file with the same name but the other extension (.pdf, .xml) is missing. To implement a variable FLAG to indicate there are missing files, simply append & set "FLAG=missing" to each for line and ensure FLAG is empty initially. Then you can check it later by simply using if defined FLAG.
Note: This does not cover the e-mail notification issue. Since I do not know the BLAT tool you mentioned, I have no clue how you want to transfer the listed files to it (command line arguments, temporary file, or STDIN stream?).
In case there is a huge number of files in the target directory, another approach might be better in terms of performance, provided that the number of file system accesses is reduced drastically (note that the above script accesses the file system within the for loop body by if exist, hence for every iterated file individually). So here is an attempt relying on a temporary file and the findstr command:
#echo off
pushd "E:\TestBat\Test" || exit /B 1
rem // Return all orphaned `.pdf` files:
call :SUB "*.pdf" "*.xml"
rem // Return all orphaned `.xml` files:
call :SUB "*.xml" "*.pdf"
popd
exit /B
:SUB val_pattern_orphaned val_pattern_missing
set "LIST=%TEMP%\%~n0_%RANDOM%.tmp"
> "%LIST%" (
rem // Retrieve list of files with one extension:
for %%F in ("%~2") do (
rem /* Replace the extension by the other one,
rem then write the list to a temporary file;
rem this constitutes a list of expected files: */
echo(%%~nF%~x1
)
)
rem /* Search actual list of files with the other extension
rem for occurrences of the list of expected files and
rem return each item that does not match: */
dir /B /A:-D "%~1" | findstr /L /I /X /V /G:"%LIST%"
rem // Clean up the temporary file:
del "%LIST%"
exit /B
To understand how it works, let us concentrate on the first sub-routine call call :SUB "*.pdf" "*.xml" using an example; let us assume the target directory contains the following files:
AlOnE.xml
ExtrA.pdf
sAmplE.pdf
sAmplE.xml
So in the for loop a list of .xml files is gathered:
AlOnE.xml
sAmplE.xml
This is written to a temporary file but with the extensions .xml replaced by .pdf:
AlOnE.pdf
sAmplE.pdf
The next step is to generate a list of actually existing .pdf files:
ExtrA.pdf
sAmplE.pdf
This is piped into a findstr command line, that searches this list for search strings that are gathered from the temporary file, returning non-matching lines only. In other words, findstr returns only those lines of the input list that do not occur in the temporary file:
ExtrA.pdf
To finally get also orphaned .xml files, the second sub-routine call is needed.
Since this script uses a temporary file containing a file list which is processed once by findstr to find any orphaned files per extension, the overall number of file system access operations is lower. The weakest part however is the for loop (containing string concatenation operations).

Batch file to generate n amount of folders

Hi I would like to create a batch file which makes n amount of folders and moves them to a specified dir. something like make folders {00001-00009} to put it bluntly. I don't want to manually put each number in and I would like to be able to exclude numbers as well.
so far I have tried this code below. I get the 5 folders made in C:\source\
and I am able to dictate how they are named to an extent, by changing j=5 to whatever integer, however sometimes the file makes folders from 00256-003372 instead of what I specified. this happens when I change j to j=256 and run the program.
echo off
cd C:\source\ :: I included this because for some reason folder 1 copied to root
SET /a j=1
:floop
IF %j%==5 GOTO END
md 00%j%
cd 00%j%
SET /a j=%j%+1
cd C:\source\
GOTO FLOOP
:end
The other way I did this was to manually input each number in a .bat file such as below. which works fine but I have to make a line for each folder.
md C:\Device_Numbers_Folder\00001
md C:\Device_Numbers_Folder\00002
P.S I named the dir file source because I am running a bunch of .bat files with CALL and this is the source part.
I think you want something like this:
#echo off
setlocal EnableDelayedExpansion
::CD "C:\source\"
::only change these three lines
set "start=1"
set "amount=5"
set "length=5"
set "exclude=4,5"
set "excluded=0"
FOR %%G IN (%exclude%) DO (set /a "excluded+=1")
set /a "last=%start%+%amount%+%excluded%"
for /l %%i in (%start%,1,%last%) do (
set "skip=0"
FOR %%G IN (%exclude%) DO (if "%%i"=="%%G" set "skip=1")
if !skip! equ 0 (
set "folderName=0000000000%%i"
set "folderName=!folderName:~-%length%!"
md "!folderName!"
)
)
In this start is the first number, amount is the amount of folder it needs to create, and length is the lenght of the names of the new files, so 1 with length 5 becomes 00001. Exclude is an comma seperated list of all the numbers not allowed

copy file based on content - command prompt

I got a folder with bunch of files in it. each file name has unique date ex: 20140101. each file has data of one product.. ex: 20140101 has data for product "oranges" file 20140102 has data of product "apple" .. I need to create a script which will check the content of file and if match found, copy the file to different directory.
Example:
Find "Oranges" in
C:\Data\
found 2 files .. 20131229 and 20140101
copy files to c:\oranges\
Thanks in advance.
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=c:\data\*.*"
set "target=c:\"
set "classes=orange apple"
for %%c in (%classes%) do (
if not exist "%target%%%c\" md "%target%%%c\"
for /f "delims=" %%f in ('findstr /m /l /c:"%%c" "%source%"') do (
copy "%%~ff" "%target%%%c\"
)
)
For each of the indicated classes, create target directory if it does not exist, and for each file with the indicated content, move it to the adecuated directory (not tested, adapt as needed)

Put files automatically in folders

I have thousands of JPGs named like this "aaa0001.jpg, aaa0002.jpg, aaa0003.jpg,
bbb0001.jpg, bbb0002.jpg, bbb0003.jpg, ccc0001.jpg, ccc0002.jpg, ccc0003.jpg etc." in one folder.
I have created 26 folders like this aaa, bbb, ccc, ddd etc.
Is it possible to create a script that sets all the images in the appropriate folder?
Result "aaa0001.jpg, aaa0002.jpg, aaa0003.jpg" into folder "aaa",
"bbb0001.jpg, bbb0002.jpg, bbb0003.jpg" into folder "bbb" etc.
Thank you!
My system is windows XP prof SP3...
It would go like this in a Windows/dos batch file.
The statement %fp:~0,3% determines which part of the filename is used as a foldername. 0,3 means: from the first character and the next 3 chars.
so a file named aaa001-01.jpg will give a folder of aaa.
To have files named abc001_03.jpg go into folder 001 you change the statement to %fp:~3,3%
for %%a in (*.jpg) do call :copyfile %%a
goto :eof
:copyfile
set fp=%1
set folder=%fp:~0,3%
rem remove echo on the next line...
echo copy "%1" "%folder%"
rem or for moving: move /Y "%1" "%folder%"
goto :eof
Just define the base path to create the news directorys in the VAR $path
#echo off
setlocal EnableDelayedExpansion
:::The path where the new Directorys will bw created
set $path="c:\Image\"
for %%a in (*.jpg) do (set $file="%%a"
set $Dir="%$path%CSV!$file:~4,3!"
if not exist "!$dir!" md "!$dir!"
move "!$file!" "!$dir!")
echo Terminated

Resources