Edit1:
So it seems my loop runs to the very last record and then executes the mkdir and MOVE commands. I feel like I'm missing parentheses somewhere?
FOR %%i IN (%folderPath%\*.Pdf) DO SET fileName=%%i
ECHO %fileName%
FOR /f "tokens=3-4 delims=_" %%a IN ("%fileName%") DO SET fileClientID=%%a_%%b
ECHO %fileClientID%
REM Check to see if folders exist, and if they do not, create them
IF NOT EXIST "%folderPath%\%fileYear%" mkdir %folderPath%\%fileYear%
IF NOT EXIST "%folderPath%\%fileYear%\%fileMonth%" mkdir %folderPath%\%fileYear%\%fileMonth%
IF NOT EXIST "%folderPath%\%fileYear%\%fileMonth%\%fileClientID%" mkdir %folderPath%\%fileYear%\%fileMonth%\%fileClientID%
REM Moves the file from source path to destination path
SET fileSourcePath="%fileName%"
SET fileDestPath="%folderPath%\%fileYear%\%fileMonth%\%fileClientID%"
MOVE "%fileSourcePath%" "%fileDestPath%"
PAUSE
So I finally finished the code and it all works as it should. I really appreciate everyone's help getting me to this point as this is my first batch file script I've ever written. Final product below and of course if there are any best practices or more efficient ways of writing it, I'd love the feedback. Thanks again!
#ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
SET folderPath="C:\Users\nha\Desktop\FolderMover\Test"
FOR %%a IN (%folderPath%\*.Pdf) DO (
SET fileDate=%%~ta
SET fileName=%%a
FOR /f "tokens=1,3 delims=/, " %%a IN ("!fileDate!") DO (
SET fileYear=%%b
SET fileMonth=%%a
For /f "tokens=3-4 delims=_" %%a IN ("!fileName!") DO (
SET fileClientID=%%a_%%b
IF NOT EXIST !folderPath!\!fileYear!\!fileMonth!\!fileClientID! mkdir !folderPath!\!fileYear!\!fileMonth!\!fileClientID!
SET fileSourcePath=!fileName!
SET fileDestPath=!folderPath!\!fileYear!\!fileMonth!\!fileClientID!
MOVE !fileSourcePath! !fileDestPath!
)
)
)
Related
Sadly I couldn't yet manage find a working solution but hopefully this time.
Long story short, we got a printer and we are currently unable to configure the scanfolder to our network drives. So I need a script to rename and move the files but keep them all.
As far as I managed to come I got a smart idea to move the files into a firstfolder to avoid that the files are overwritten. Next I need to either rename the files with a counter or move them and keep them all.
I choose the rename option since this seems more simple but I ran into one big issue.
I have no idea how I make it work. So what I'm trying is to first set the variable and do a first test calculation. Just for a first quick test. Now it already works for the first count but sadly it doesn't count up as hoped since he does the rename for all the files before increasing the value of the variable so only one file is renamed.
#ECHO off
::Defining Variables
setlocal EnableDelayedExpansion
SET N=0
ECHO %N% Hi Not rename
SET /a N=%N%+1
FOR /L %%A in (1,1,10) DO (
Echo !N! hi
RENAME "C:\Users\smorheng\Desktop\1\*.pdf" "Test.?????.!N!.*" | SET /a N=!N!+1
ECHO !N! Hi Not rename
timeout 3 /nobreak > nul
)
ECHO RENAME DONE
timeout 50 /nobreak > nul
About 20 Files are renamed to something like Test.1.pdf, Test.2.pdf .... Test.20.pdf and then moved to their destination.
The moving is not an issue but if I could manage to get this feature working I can adapt it to whatever I need.
You can simply move the files, but first check if the file exists in destination, if it does, rename it using a numeric value after the name. Here is something that might work. You just need to change source and destination folder below. The actual move will not occur as I added echo to the second last and last line to demonstrate what it will do, if it works, simply remove echo from both lines.
#echo off
setlocal enabledelayedexpansion
set "source=C:\Users\smorheng\Desktop\1\"
set "dest=D:\destination\folder"
set /a cnt=0
for /f "tokens=*" %%a in ('dir /S /B /A-D "%source%*.pdf"') do for /f "tokens=*" %%b in ('dir /B "%%a"') do if exist "%dest%\%%b" (
set "ext=%%~xa"
set "fname=%%~na"
if exist "%dest%\!fname!(!cnt!)!ext!" (set /a cnt=!cnt!+1)
set /a cnt=!cnt!+1
echo move "%%a" "%dest%\!fname!(!cnt!)!ext!"
) else echo move "%%a" "%dest%\%%b"
Also note, this will recursively move all files from within the directory tree, if you only want to go into the first directory, simply remove /S from the for loop which will then simply become dir /B /A-D "%source%*.pdf"
Edit
As for your for /L loop (mentioned in comment)
Rather have a label and permanently goto it after completed. Here is a simple example of something like that, copy it to a script and run it, see the result:
#echo off
:label
echo Hi, this will run every 6 seconds and print this line. (infinitely).
timeout 6>nul
goto :label
So technically you can do the exact same for your loop, for instance:
#echo off
:label
setlocal enabledelayedexpansion
set "source=C:\Users\smorheng\Desktop\1\"
set "dest=D:\destination\folder"
set /a cnt=0
for /f "tokens=*" %%a in ('dir /S /B /A-D "%source%*.pdf"') do for /f "tokens=*" %%b in ('dir /B "%%a"') do if exist "%dest%\%%b" (
set "ext=%%~xa"
set "fname=%%~na"
if exist "%dest%\!fname!(!cnt!)!ext!" (set /a cnt=!cnt!+1)
set /a cnt=!cnt!+1
echo move "%%a" "%dest%\!fname!(!cnt!)!ext!"
) else echo move "%%a" "%dest%\%%b"
endlocal
timeout 6>nul
goto :label
Try replacing "RENAME" to SET newname see if that helps?
EDIT or try a vbs script instead of a batch?
`Set objFS = CreateObject("Scripting.FileSystemObject")
strFolder="c:\test"
Set objFolder = objFS.GetFolder(strFolder)
For Each strFile In objFolder.Files
If objFS.GetExtensionName(strFile) = "jpg" Then
strFileName = strFile.Name
If InStr(strFileName,"XXXXXXX") > 0 Then
strNewFileName = Replace(strFileName,"XXXXX","YYYYY")
strFile.Name = strNewFileName
End If
End If
Next `
I am new to Batch script,
by using the following code
setlocal enabledelayedexpansion enableextensions
set LIST=
for %%x in (D:\all_files\*.csv) do set LIST=!LIST! %%x
set LIST=%LIST:~1%
echo %LIST%
i am getting the filenames with directory and also with a Paragraph
but i need file names alone one by one like below into a Variable of %LIST%
file1.csv
file2.csv
file3.csv
can any one please help us
I hope, I got your intentions right.
Instead of a variable, just loop over output of dir /b
:loop
echo still waiting...
timeout /t 10
set "ok=yes"
for /f "delims=" %%a in ('dir /b "D:\all_files\*.csv"') do (
if not exist "C:\%%a" set "ok=no"
)
if "%ok%" == "no" goto :loop
echo all there...
call process1.bat
We have many Oracle-Database-Client versions in our company.
The tnsnames.ora will be changed often.
I like to create a package (batch) to backup (rename) the present file in all versions of Oracle Client (if there are two or more versions installed) and after that, copy the new file.
My script for now looks so:
setlocal enabledelayedexpansion
set /a count=0
set OracleDir="%SystemDrive%\oracle\product"
for /d %%i in (%OracleDir%\*) do (
set dir=%%i\client_1\network\admin\
PushD !dir:\\=\!\
for /f "tokens=*" %%a in ('dir /b /od tnsnames.ora') do (
rename "%%a" "tnsnames-%Date%-Backup-!count!.bak"
)
set /a count+=1
IF NOT EXIST "%%i\client_1\network\admin\tnsnames.ora" (
copy "%~dp0tnsnames.ora" "%%i\client_1\network\admin\" /Y
)
)
endlocal
So far so good. But the script will only create a backupfile once.
But it must create a new "tnsnames-%Date%-Backup-!count!.bak" everytime I run the script.
Hope you know what I mean?
I'm sure, i need a jump point somewhere but no idea where.
IMO you did overcomplicate things.
The inner for is useless doing a dir for a file at a fixed location. This is better checked with an if exist.
If you then rename that file the next if is also useless, it can't exist - you just renamed it (better check if the rename was succesful)
setlocal enabledelayedexpansion
set /a count=0
set OracleDir="%SystemDrive%\oracle\product"
for /d %%i in (%OracleDir%\*) do (
set "dir=%%i\client_1\network\admin\"
PushD "!dir:\\=\!\" || (Echo couldn't pushd "!dir:\\=\!\"&Pause)
Set "Stamp=!Date!.!Time:~,2!.!Time:~2,2!"
if exist tnsnames.ora if not exist "tnsnames-!Stamp!-Backup.bak" (
rename tnsnames.ora "tnsnames-!Stamp!-Backup-!count!.bak"
)
set /a count+=1
if not exist tnsnames.ora copy "%~dp0tnsnames.ora" "!dir!"
PopD
)
endlocal
I am trying to write a batch file to find and replace a string in multiple files within a folder. But I am getting this error:
Cannot perform a cyclic copy
Any idea why that happens?
#echo off
SETLOCAL
for %%* in (.) do set foldername=%%~n*
SET stringtofindreplace=XXXX
for %%f in (*.fmw) do (
echo Processing %%f...
fOR /F "delims=" %%l IN (%%f) DO (
SET "line=%%l"
SETLOCAL ENABLEDELAYEDEXPANSION
set "x=!line:%stringtofindreplace%=%foldername%!"
echo(!x!
ENDLOCAL)
)>%%~nf.new
)
GOTO:EOF
#ECHO OFF
SETLOCAL
:: no idea what this is aimed at doing...??
for %%* in (.) do set new=%%~n*
SET new=newstring
SET old=XXXX
for %%f in (*.fmw) do (
echo Processing %%f...
(
FOR /F "delims=" %%l IN (%%f) DO (
SET "line=%%l"
SETLOCAL ENABLEDELAYEDEXPANSION
set "x=!line:%old%=%new%!"
ECHO(!x!
ENDLOCAL
)
)>%%~nf.new
)
GOTO :EOF
I've no idea what you are trying to do with the first for, so I just made an obvious replacement string.
You need to add the "delims=" option to deliver the entire line to %%l.
Make sure there are no trailing spaces on the ECHO(!x!
This will make a new file called *.new from each *.fmw file.
Cannot perform a cyclic copy error occurs when the source folder includes the target folder, and so is trying to copy all the files, including the files it has already copied.
This will give you that error.
xcopy c:\apple\*.* c:\apple\backup\ /s
Ok, I am trying to make a batch file to generate a series of files and folders, but can't find on how to do it.
My Idea:
FOR /f "Tokens=* delims=" %%I IN (export2.csv) DO call:create %%I GOTO:EOF
:create ECHO 1 >>%~pd0%1
But it didn't work at all.
Since I have no idea how your data file looks like it's hard to give good advice here, but your code could be cleaned up a bit:
set "filepath=%~dp0"
for /f "tokens=* delims=" %%I in (export2.csv) do call :create "%%I"
rem This is needed to avoid stepping into the subroutine again
goto :eof
:create
rem This will create an empty file instead of one that contains a single line with 1
copy nul "%filepath%%~1"
goto :eof
This won't create any directories, though. You can create those with md.
Figured it out a little bit ago and here is what I ended up with. It will generate both the path and create an empty file with the name of the file listed in the masterlist.csv.
Source Code
#ECHO OFF
CHDIR "%~dp0"
SET Count=0
ECHO/ Generating Necessary File, please Wait...
FOR /F %%A IN (Masterlist.csv) DO CALL:MKDIR %%A
EXIT /B
:MKDIR
SET /A Count+=1
SET "Path=%~dp1"
SET "File=%~nx1"
IF NOT EXIST "%Path%" MKDIR "%Path%
IF NOT EXIST "%Path%" CALL:ERROR "Path"
IF NOT EXIST "%Path%\%File%" ECHO/ >>"%Path%\%File%"
IF NOT EXIST "%Path%\%File%" CALL:ERROR
EXIT /B
:ERROR
IF NOT EXIST "Errorlog.csv" ECHO Error, Line Count>>Errorlog.csv
ECHO %~1, Line %Count%>>Errorlog.csv
A few example lines from Masterlist.csv
2006\MS06-003\Office2000\office2000-kb892842-fullfile-enu.exe
2006\MS06-003\Office2003\office2003-kb892843-fullfile-enu.exe
2006\MS06-003\Office2003\WinSec-MS06-003-009-P44333-outlook2003-kb892843-fullfile-enu.exe
2006\MS06-003\OfficeXP\officexp-kb892841-fullfile-enu.exe
2006\MS06-006\WindowsMedia-KB911564-x86-ENU.exe
2006\MS06-007\2003\WindowsServer2003-KB913446-x86-ENU.exe
2006\MS06-007\XP\WindowsXP-KB913446-x86-ENU.exe
2006\MS06-012\2003\office2003-KB905756-FullFile-ENU.exe
2006\MS06-015\2000\Windows2000-KB908531-x86-ENU.EXE
2006\MS06-015\2003\WindowsServer2003-KB908531-x86-ENU.exe