Windows batch file - process one file at a time - windows

Odd question - but it's driving me a bit crazy. I have a directory where multiple files can be dumped via FTP, then I need to process them one at time. So basically in this directory I could have 1.txt, 2.txt, 3.txt etc then I need to:
copy the file to an archive (if exist copy to archive)
move the file to one specific filename one at a time - data.txt <--- this is what's getting me
run a command on a legacy backend system client using that specific filename (data.txt)
run another command on legacy client using data.txt
delete data.txt
Move on to the next file and repeat
So far I've tried several methods of do loops without any luck - they all get hung up on trying to rename multiple files into one file, and that just kills me. I'd long ago since given up on batch files but annoyingly, this application has to use windows, and Server 2003 to boot.
EDIT: Here's what I've tried-
This works to do one file at a time:
if exist c:\jail\ftp*.txt copy c:\jail\ftp*.txt w:\scans\archive*.txt
if exist c:\jail\ftp*.txt move c:\jail\ftp*.txt w:\data.txt
if exist w:\data.txt C:\temp\rmtcmdb.exe
if exist w:\data.txt del w:\data.txt
I've tried multiple for loops without success, here is the latest (NOTE - I'm just trying to get past the move stage on this one, once I'm done with that I'll add in the rest):
setlocal ENABLEDELAYEDEXPANSION
FOR /f %%a IN ("c:\jail\ftp\") DO (
CALL SET /A x = !x! +1
if !x! == 1 (
CALL copy %%a w:\scans\archive*.txt
CALL move %%a w:\data.txt
)
)
I've also tried some very basic for loops, and again - nothing is getting past the move stage.
Any suggestions?

#echo off
setlocal enableextensions
for %%a in ("c:\jail\ftp*.txt") do (
set "fileName=%%~na"
setlocal enabledelayedexpansion
copy "%%~fa" "w:\scans\!fileName:*ftp=archive!%%~xa"
endlocal
move /y "%%~fa" "w:\data.txt"
start "" /wait "c:\temp\rmtcmdb.exe"
if exist "w:\data.txt" del /s "w:\data.txt" >nul 2>nul
)

Related

How could i copy multiple files 1 at a time from 2 folders to another folder with a windows batch file or vbs script

I am working with a video camera and we have a program that displays the saved videos from an SD card when inserted into a PC. At some point the manufacturer of the camera changed the directory structure and naming convention for the saved files. I would like to create a batch file or VBS Script that will reorganize the files into the old structure. This will be a quick and dirty fix for windows based PC's and until we can re-write the software which will include support for MAC's. It can be a batch file or a VBS Script but must run under a Windows command prompt with no additional software installed. The camera has front and rear cameras so there are 2 files to deal with and there could be 1 or more video captures to relocate.
The number of folders would depend on the number of videos saved, let's say there are 4 videos saved so the original structure looked like this.
- video1
- video.TS
- video2.TS
- video2
- video.TS
- video2.TS
- video3
- video.TS
- video2.TS
- video4
- video.TS
- video2.TS
The new structure looks like this
- Normal
- F
- DATETIME-000001F.TS
- DATETIME-000002F.TS
- DATETIME-000003F.TS
- DATETIME-000004F.TS
- R
- DATETIME-000001R.TS
- DATETIME-000002R.TS
- DATETIME-000003R.TS
- DATETIME-000004R.TS
The object is to move these files into the older file structure so the software can read and display them. I already have a batch file that runs when the SD card is inserted so my assumption is that I can include some script before the normal process fires to move these files around. I am pretty rusty with scripting and need some guidance.
My current script look like this.
setlocal enableextensions enabledelayedexpansion
set count=0
for %%x in (\Normal\F\*.TS) do (
set /a count += 1
mkdir video!count!
move /Y \Normal\F\*.TS \video!count!\video.TS
move /Y \Normal\R\*.TS \video!count!\video2.TS
)
endlocal
There are always 2 videos, 1 for the front camera and 1 for the rear camera so I am only using the "F" directory to get the count.
Without the move commands it creates the directory structure just fine... If there is 1 file it only creates 1 folder, if there are 8 files it creates 8 folders. but when there are multiple files it wants to put all of the files in the first folder.
I assume I would need to nest another loop but everything I have tried has failed and this is the closest attempt.
#ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include 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"
SET "destdir=u:\your results"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\normal\F\*-*.ts" '
) DO (
SET "video2=%%~na"
SET "video2=!video2:~0,-1!R%%~xa"
FOR /f "tokens=2delims=.-" %%i IN ("%%a") DO (
SET "video=%%i"
SET /a video=1!video:~0,-1!-1000000
MD "%destdir%\video!video!" 2>NUL
MOVE /y "%sourcedir%\normal\F\%%a" "%destdir%\video!video!\video.TS" >NUL 2>nul
MOVE /y "%sourcedir%\normal\R\!video2!" "%destdir%\video!video!\video2.TS" >NUL 2>nul
)
)
)
GOTO :EOF
You would need to change the values assigned to sourcedir and destdir to suit your circumstances. The listing uses a setting that suits my system.
I deliberately include spaces in names to ensure that the spaces are processed correctly.
First, assign to %%a each filename found in the ...\F directory.
Then construct the corresponding filename in ...\R by taking the name part of %%a, removing the last character and replacing it with R, then appending the extension from %%a.
Next, derive the sequence number from %%a by selecting the second token from %%a using - and . as delimiters. Set the number part of the destination directoryname by prefixing all bar the last character of video with 1 and subtracting 1000000 to convert it to the natural form.
Create the destination directory and move in and rename the source files
[edit in response to comments]
#ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
SET "drives=d e f g h i j k l m n o p q r s t u v w x y z"
SET "sourcedir=normal"
:: locate drive that has directory "?:\normal\f"
FOR %%d IN (%drives%) DO IF EXIST "%%d:\%sourcedir%\f\." SET "sourcedir=%%d:\%sourcedir%"&SET "destdir=%%d:\video"&GOTO founddrive
ECHO Could not find "%sourcedir%\f" on any drive
GOTO :eof
:founddrive
SET /a destnum=1
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\f\*-*.ts" '
) DO (
MD "%destdir%!destnum!" 2>NUL
SET "filename=%%~na"
set "filename=!filename:~0,-1!R%%~xa"
MOVE /y "%sourcedir%\F\%%a" "%destdir%!destnum!\video.TS" >NUL 2>nul
MOVE /y "%sourcedir%\R\!filename!" "%destdir%!destnum!\video2.TS" >NUL 2>nul
SET /a destnum+=1
)
GOTO :EOF
OK, so this version first scans for the directoryname, then picks the files and places them, with namechanges, in directory video1... on the same drive.

Mass delete file extension batch file

Hello I have a batch file I've created to delete all files of a certain extension that it asks for when you run it. I need to delete 2,111,000 .txt files and the batch file only deletes 3 at a time which will take forever to delete the files. Is there a way I can make it faster or if somebody has a better code to do this?
Here is my code:
#ECHO OFF
CLS
SET found=0
ECHO Enter the file extension you want to delete...
SET /p ext="> "
IF EXIST *.%ext% ( rem Check if there are any in the current folder :)
DEL *.%ext%
SET found=1
)
FOR /D /R %%G IN ("*") DO ( rem Iterate through all subfolders
IF EXIST %%G CD %%G
IF EXIST *.%ext% (
DEL *.%ext%
SET found=1
)
)
IF %found%==1 (
ECHO.
ECHO Deleted all .%ext% files.
ECHO.
) ELSE (
ECHO.
ECHO There were no .%ext% files.
ECHO Nothing has been deleted.
ECHO.
)
PAUSE
EXIT
Can I make this go faster?
The quickest way I can imagine is just:
cd /BASE_PATH
del /s *.txt
You're probably better just letting the OS sequentially delete files rather than trying to delete multiple files in parallel anyways. If you're using a mechanical HDD as opposed to an SSD, you could have files on different platters, heads, sectors, etc, and depending how much load you put on an I/O bound resource, the overall operation takes more time since the drive has to seek data all over the place. Plus, random access on an HDD is abysmal.
You might want to try it this way:
DIR C:\*.txt /S /B > filelist
FOR /f %%i in (filelist) DO ECHO DELETE %%i
Remove the 'ECHO' when you are sure you want to run this ;-)
But this only makes sense when you want to process each file separately, for logging purposes for example. If not, then #Dogbert solution is shorter.

Move specific files out of subfolders and delete said subfolders

I recently exported the HDD on my panasonic camera to my notebook and noticed that the video files weren't ordered by name, but by their parent directory and said parent directory was clouded with a bunch of miscellaneous files.
To put things into perspective, the directory tree looks something like this:
\Panasonic
\PRG00A
\PRG00B
...
\PRG069
Panasonic is located inside a bunch of folders, hence why I would like to put my batch file alongside \Panasonic. And have it work relatively to its location.
So basically I want to create a batch file move.bat, which shall traverse the subdirectories of \Panasonic and move out any video files (with extension .MOD to simplify things) and afterwards delete the parent directory (e.g. \PRG00B).
The result would be that the \Panasonic directory only includes video files instead of sub-directories with a bunch of rubbish.
What I've got so far (keep in mind that this is my first batch script, and I haven't even tested it fully). The choice to continue doesn't work, by the way. Not sure why, though.
#echo off
cls
set dirName=%~dp0Panasonic
goto question
:start
goto move
goto end
:move
for /D %%G in ("%cd%") do (
for %%I in ("%%G") do (
if %%I equ "*.MOD" (
move /Y %%I %dirName%
)
)
rmdir /s /q %%G
)
:end
echo Done.
pause
endlocal
exit
:question
set /P c="Are you sure you want to proceed with moving video files from %dirName%? [Y/N]"
if /I %c% equ 'y' (
echo Moving files...
goto start
) else (
goto end
)
Once again, this is my first time creating a batch file, so any help is much appreciated!
you are almost there, but just need to fix a couple of things, very easy to fix, in fact, you just need to simplify a lot your code.
Just in three simple steps
Step 1. To loop over all the directories you already had it right, your friend is for /d
for /d %%a in (*) do echo %%a
Step 2. To move all the .mod files in each of the directories found, to its parent directory or one directory up in the hierarchy, that happens to be the current directory, you just need to
move %%a\*.mod .
don't use /y option, so it will not overwrite existing files already moved to the parent directory (You will have the opportunity the check the results later. Keep reading)
Step 3. And finally, remove the directory,
rd %%a
but don't use /s, so it will only work it the directory is empty, that is, if you have successfully moved out all of the files it contained. This way you can then browse thru them to see what is left without losing any data.
So, your moveupallmod.bat becomes simply
#echo off
for /d %%a in (*) do (
move "%%a\*.mod" .
rd "%%a"
)
and that's all!

Move files to folders based on file name

I am new to batch files although have searched thoroughly and found topics with a similar BUT not covering what I need.
I work with lots of documents (.pdf, .doc, .xls ) saved in C:\Tempfolder. once I am done editing I save the file name with 9 digit numbers e.g( 305123123.pdf or 306123123.pdf or .doc )
I am looking to create a batch file which will automate move the files that start with
305 to C:\Users\Omer\Documents\aaCompany or if
306 to C:\Users\Omer\Documents\bbCompany
I can have upwards of 200 files in the folder at any one time when I decide to process.
I am also curious if the batch file can monitor C:\Tempfolder and move the files 305 or 306 without executing it
Help on this is greatly appreciated.
I hope I have provided sufficient information to see if this is feasible.
You can make something like this :
#Echo off &cls
::The Input Folder
set $Dossier="C:\Tempfolder"
::The Output Folders
set $Out305="C:\Users\Omer\Documents\aaCompany"
set $Out306="C:\Users\Omer\Documents\bbCompany"
::The extensions to wait
set "$Format=*.pdf,*.xls,*.doc"
setlocal enabledelayedexpansion
:Boucle
cls&echo Waiting for file ...
for /f %%a in ('dir /b/a-d %$Dossier%\%$Format% 2^>nul') do (
set "$Fichier=%%a"
echo Treating -^> %%a
if "!$Fichier:~0,3!"=="305" move "%%~nxa" %$Out305%
if "!$Fichier:~0,3!"=="306" move "%%~nxa" %$Out306%
)
::Waiting ~5 secondes
ping localhost -n 6 >nul
::Return to the loop
goto:Boucle

BATCH FILE - IF Exists & Output Error

INFO: assets.txt contains a list of cpu names which I can connect to over the network.
I need to copy this new .exe to well over 200+ computers and figured i could use the c$ admin share. This is really the only way I can do this without going to workstations individually or remoting in one by one.
This script works without the 'if exists' however I need to check if the directory exists before attempting the copy. I don't understand why it isn't working. I am also running this script using my domain administrative account.
#echo off
REM Pull Computer Asset Tags from file
for /F "tokens=*" %%A in (assets.txt) do (
echo Start Processing %%A
REM Temporarily set file path for existence check
set file=\\%%A\C$\Program Files\Intouch2\Intouch2ca.exe
if EXIST "%file%" (
REM Rename old .exe
ren "\\%%A\C$\Program Files\Intouch2\Intouch2ca.exe" "Intouch2ca.bak"
REM copy new .exe from server to cpu asset
xcopy "\\server\my dir\management\it\software\Intouch Upgrade\Intouch2ca.exe" "\\%%A\C$\Program Files\Intouch2\" /Y
echo END Processing %%A
echo.
echo ------------------------------------------------------------
echo.
)
)
I also haven't been able to get the error output to a log file.
I have tried this but it isnt exactly what I would like.
xcopy "\\server\my dir\management\it\software\Intouch Upgrade\Intouch2ca.exe" "\\%%A\C$\Program Files\Intouch2\" /Y 1>>errors.log 2>&1
How can I pretty that up so it only shows errors and lists the %%A where the error occured?
Thank you all in advance for your time.
Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed.
Hence, in your case, file is being changed within the block, so the value cmd uses is its initial value when the entire for is parsed.
Solution 1: use \\%%A\C$\Program Files\Intouch2\Intouch2ca.exe in place of %file%
Solution 2: start your batch with setlocal enabledelayedexpansion on a separate line after the #echo off, then use !file! in place of %var%
Solution 3: call an internal routine to use the mofified value as %file%
Solution 4: Create the directory regardless. MD newname 2>nul will silently create a new directory if it doesn't already exist
An error on a copy will set an errorlevel and you can write a custom error message.
copy "\\server\my dir\management\it\software\Intouch Upgrade\Intouch2ca.exe" "\\%%A\C$\Program Files\Intouch2\" >nul 2>&1
if errorlevel 1 >> errors.txt echo "Error in %%A"

Resources