dos batch file find missing sequential filenames - batch-file

Here is the situation, I have directories that have 10,000 files in each directory named like this:
FileName.XX0000.csv
FileName.XX9999.csv
The Size of the filename itself can change ie:
FileName.XXX0000.csv
FileName.XXX9999.csv
FileName.XXXX0000.csv
FileName.XXXX9999.csv
Where the X's are yet another parent number, but these ones should be ignored anyway.
Regardless though all directories are supposed to have exactly 10,000 files no more and no less. The trouble is some are missing and I need to know which ones are missing.
I tried the scripts in this post:
batch script to find missing sequence no
I even messed around with the string sequnce for several hours to no avail. Neither of these options works very well the 2nd script comes close but ends up in an endless loop, or spits out files that do exist.
I need to come up with a solution that will easily tell me which numbers or file names are missing. In my Dream world I would love a script where I can place it inside a parent directory and it would crawl through all the sub directories and print a single file of the missing ones.
It would be nice to not have to tell the script what the beginning part of the file name is, since in theory it should only be looking to see if the last four numbers are in existance from 0000-9999.
Since this is my first post I am hoping I doing this correctly by creating a new topic, I was going to ADD my question to the previous topic until I saw the "But avoid …" in the post box!

Let's see if you can write some code.
FOR /L can count from 0 to 9999
IF NOT EXIST can test if a file is missing, and it supports wild cards.
> and >> can redirect output to a file
For your dream world:
FOR /D /R %%F IN (.) will iterate an entire folder hierarchy
Edit
You probably will need to left pad a number with zeros so that the width is always 4 digits. Since this will probably be within a loop, you will want to use delayed expansion. Assume %%N is a FOR variable that contains a number.
set num=000%%N
set num=!num:~-4!

Here is a script that will find all the missing files in a continuous sequence:
#echo off
setlocal ENABLEDELAYEDEXPANSION
set max=1208
set cnt=0
for /L %%f in (0,1,%max%) do (
set "num=00000%%f"
set "num=!num:~-4!"
if not exist "img!num!.png" (
echo img!num!.png
set /A "cnt=!cnt!+1"
)
)
echo NUMBER MISSING: !cnt!
endlocal
Notice inside the loop you need to use !x! instead of %x% to get a local delayed variable.

Related

Windows bat file to rename multiple files with custom names

I have multiple folders with multiple files in each of them. The file names are as following: static-string-1.wav static-string-2.wav .... static-string-10.wav ... static-string-99.wav static-string-100.wav ... and so on. The static string remains same but the number before .wav changes from 1 - 999. Now the problem is if I want to play this on any media player or want to join all the files, windows will sort like 1,10,100,2,20,200 not 1,2,3,4,5,6,7,8,9,10 which messes up the playback. So to fix this, I have to rename each file from static-string-1.wav to static-string-0001.wav and so on.
Currently, I am doing a dir command to an output file and then I copy the file list in excel from where I do some playing around with concatenate and text to columns and come up with two columns of old name and new name which I then again convert to a .bat file with and run it. The bat file has multiple rows with individual rename commands something like this:
#echo off
rename <oldname1> <newname0001>
rename <oldname2> <newname0002>
.
..
exit
It is getting the work done but I know there is and easier and more efficient way to use for loops. I saw few example and previous answers but they dont have a similar requirement as me. Any help will be appreciated.
Leading zeros can be added and (later) truncated if not needed. This question is a possible duplicate, but I don't like how files are sorted like that either.
Delaying the expansion allows b to change within the for loop instead of being static (haha puns) throughout the whole program. Therefore you can increment b each loop and rename the files. This is a simple example:
#echo off
setlocal ENABLEDELAYEDEXPANSION
for /l %%a in (1,1,99) do (
set b=00%%a
rename static-string-%%a.wav static-string-!b:~-2!.wav
)
This should work. Contact me if you need more help
Below is a significant improvement to Clayton's answer
Only numbers less than 100 need be modified
The script automatically works with any static prefix. See How does the Windows RENAME command interpret wildcards? for an explanation of how this works.
The script reports any file names that could not be renamed
#echo off
setlocal enableDelayedExpansion
for /l %%N in (1 1 99) do (
set "n=00%%N"
for %%F in (*-%%N.wav) do ren "%%F" *-!n:~-3!.* || >&2 echo ERROR: Unable to rename "%%F"
)
Or, you could grab my JREPL.BAT regular expression renaming utility and simply use:
jren "-(\d{1,2})(?=\.wav$)" "'-'+lpad($1,'000')" /j

batch error "c:\ant-1.8.4\bin was unexpected at this time."

I'm just starting with batch files, and I'm trying to loop over my Path environment variable with this script:
for %%A in %PATH% do echo %%A
ant I'm getting the error in the title.
While running set I see that path has a value, and the "c:\ant-1.8.4\bin" is what I'm looking for.
I tried playing around with it, and even this:
for %%A in %PATH% do echo TEST
fails with the same error.
Thanks!
edit - clarification
In the end, I want to do a small manipulation on each entry, so Magoo's answer doesn't really solve the problem for me.
#ECHO OFF
SETLOCAL
ECHO %path:;=&ECHO(%
This should show the elements of your path one to a line. Your question isn't clear - what do you actually want to do?
Adapting answer from comments in original question
There are two different sets of parenthesis in a for command:
for %%x in (set) do (commands)
The first set of parenthesis delimit the set of elements being processed and are needed always.
The second set of parenthesis are needed only if the list of commands to execute for each of the iterations of the for command extends over several lines.
And yes, spaces, &<>!;:," and some more special characters need to be taken into consideration when dealing with for command and file/folder paths.

Comparing and moving sets of files

I need a batch file that looks in a file and moves a set of files
the problem is, is that it will need to compare files as there may be more than 1 set
the files correspond to each other
the first file in the set is BIAK1234
the second file is BIPO1234
Note the the 1234 is just the file number and will indicate what set it is a part of
So the batch file must find the set of files - BIAK1234 and BIPO1234 and move them to another file
if BIAK1234 does not exist then the script needs to end
But if there are files: BIAK1234, BIAK12345, BIPO 1234, BIPO12345 and BIPO123456
bipo123456 must remain until BIAK123456 exists and then it may be moved over
so how do I compare the files
I already know how to make a batch file move files and how to check to see if a file exists I am just not quite sure how to compare the files, determine the sets and move ONLY the sets
I struggled a bit with your question. At first I thought you were getting the file names from a text file. But your last paragraph led me to believe you are simply dealing with files in a folder.
As you say, the only moderately tricky bit is determining the individual set IDs. The solution is to use the SET command to either get a substring, or else replace the prefix with nothing. Type set /? from the command prompt to get more information.
In the solution below, I opted to use the search and replace method.
#echo off
setlocal enableDelayedExpansion
set "source=c:\yourSourceFolder"
set "destination=c:\yourDestinationFolder"
set "file1=BIAK"
SET "file2=BIPO"
pushd "%source%"
for %%F in ("%file1%*") do (
set "setID=%%F"
set "setID=!setID:%file1%=!"
if exist "%file2%!setID!" move "%%F","%file2%!setID!" "%destination%"
)
popd

Batch file to copy files based on part of filename from one server to another

I'm trying to create a batch file (via Windows XP Pro) that copies 2 files (.zpl) who's filename's vary in length. ZPL files relate to label printer code. File names are as follows:
FillXferDataPBHAMFill###########.zpl
FillFormatsPBHAMFill############.zpl
The pound signs represent a number associated with a particular label/job to be printed. These numbers are identical per job. From one job to the next the numbers vary in length and always change. The directory I'm trying to pull these from contains ZPL files from multiple locations, however, I just want the BHAM ones.
The batch will copy from: \Server\C:\Directory1\Directory2\Directory3
To be copied to: \Server\Directory1\Directory2
Not sure if this will complicate things further, but the batch file will be ran from a 3rd machine. Furthermore, I do not need to copy every file everytime. Whenever new print jobs are sent, supervisors will run the batch to copy the new print jobs within the last X amount of time. X being minutes. Here is what I have so far...
#echo off
SETLOCAL enableExtensions enableDelayedExpansion
SET sourceDir=Server\C:\Directory1\Directory2\Directory3
SET targetDir=Server\Directory1\Directory2
FOR %%a (FillFormatsPBHAM*.bat) DO (
SET "filename=%%a"
SET "folder=%targetDir%"
XCOPY "%%a" !folder!
)
FOR %%b (FillXferDataPBHAM*.bat) DO (
SET "filename=%%b"
SET "folder=%targetDir%"
XCOPY "%%b" !folder!
)
:END
I apologize for a lengthy post; just wanting to be as thorough as possible. I'm learning this on the fly so bare with any ignorance on my part. Thank you in advance for ANY help!!
StackOverFlow Material Reviewed: Reference1, Reference2 -- I've been looking everywhere over the past week and these were the 2 most helpful so far.
I see some ways to fix or improve your BAT script.
The FOR command syntax is FOR %%a IN (*.bat) DO (
The sourcedir variable is set Server\C:\Directory1\Directory2\Directory3, which is not a correct path in Windows.
you initialize but don't use %sourcedir% variabe neither in your FOR loop nor in your copy commnand
you should either change the current drive and dir with a pushd %sourcedir% command, or specifying it in the FOR command.
your FOR loop assigns a %filename% variable that is never used, you may skip this assignment.
you FOR loop assigns a %folder% variable that is only then used in the copy command, you can skip this assignment and simply use %targetdir%
but, to just copy all files from one folder to the other you don't need FOR to iterate over all of them, you might just copy them right.
So, take a look at this simple script to get you started..
SET sourceDir=\\servername\sharename\Directory1\Directory2\Directory3
SET targetDir=\\anotherserver\sharename\Directory1\Directory2
xcopy %sourceDir%\FillFormatsPBHAM*.bat %targetDir%
xcopy %sourceDir%\FillXferDataPBHAM*.bat %targetDir%

How to put a time stamp while copying files in the for loop inside the batch file

Help please! I am new to the batch files and have a very specific question. I am trying to copy many files in multiple subdirectories into a single directory via a for loop and in the meantime attache a timestamp to each name (because all the files have the same name). I am using the system variable time and parsing it inside the loop, but the local variables inside the loop get assigned garbage. I already know about delayed expansion and using ! sign instead of %, but that doesnt help me. here is the code:
#echo off
SetLocal EnableDelayedExpansion
set counter=1
echo in the beginning the counter is "%counter%"
:loop
for /r "c:\users\wimdu\dropbox\wimdu CRM\emarsys reports - campaigns" %%f in (bounce*.*) do (
set a = %time::=%
echo in loop a equals "!a!"
echo the time is !time!
set b=!a:,=!
copy /y "%%f" c:\users\wimdu\documents\bouncehandling\bouncecsvfiles\%b%.csv
)
EndLocal
So, basically the names of the files would be 10151821.csv, for instance (time stamp including milliseconds). ideally it would be the original filename (bounces) concatenated with time stamp with .csv extension. I have tried everything but with the timestamp nothing seems to work, a just does not get assigned correctly. And then b as well . I do not know how to parse a and then assign it to b within !! signs. Please help!!
There are multiple problems.
You didn't set "a" as you append a space, you set "a ".
And you always use the same time, as %time% will be expanded only once while parsing the block:.
The same problem you get with %b%.
Change both to delayed expansion and it could work.
Agree with #jeb on all the points, however there may be another problem. Depending on your locale, the result of %time% may contain a leading space when the current time is before 10 in the morning. If that is so, the target path in your COPY command gets split, since it is not enclosed in double quotes. As a result, the command becomes syntactically incorrect.
So, if you fix all the issues mentioned so far, your script should work without any problem. At least a simplified version of your script worked for me. Here's how I tested it:
First, I created a simple setup on my computer:
MKDIR C:\tests\source
MKDIR C:\tests\target
then copied several random files of moderate size to the C:\tests\source folder and ran the following script:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R "C:\tests\source" %%f IN (*) DO (
SET a=!time::=!
SET a=!a:,=!
COPY /Y "%%f" "\!a!"
)
And this is what appeared in C:\tests\target as a result:
_1395459
_1395470
_1395639
I should point out that _ is actually a space, because on my computer the result of %time% indeed contains a leading space at this hour, which is between midnight and 10 a.m. in this part of the world. Anyway, my main point is, the script I posted above (which, I stress, is basically the same as yours) has worked for me.

Resources