In a previous question of mine, Aacini provided me with this code:
#echo on
setlocal EnableDelayedExpansion
set "digits=8"
set mypath=%~dp0
cd /d "%~dp0"
rem delete old list from current even if read only
del /f list.txt
rem Assemble the factor with the proper number of digits
set "factor=1"
for /L %%i in (1,1,%digits%) do set "factor=!factor!0"
rem Accumulate size of all extensions in 2 groups of %digits% digits each
for %%a in (*.*) do (
set "size=%factor%%%~Za"
set /A "low[%%~Xa]+=1!size:~-%digits%!-factor, carry=low[%%~Xa]/factor,
low[%%~Xa]%%=factor"
set "size=%%~Za"
set "size=!size:~0,-%digits%!"
set /A "high[%%~Xa]+=carry+size"
)
rem Show results
for /F "tokens=2,3 delims=[.]=" %%a in ('set high[') do (
if %%b neq 0 (
set "low=%factor%!low[.%%a]!"
echo %%a %%b!low:~-%digits%! bytes >>"%mypath%\list.txt"
) else (
echo %%a !low[.%%a]! bytes >>"%mypath%\list.txt"
)
)
Now I'm trying to make it search through the parent directory when creating the list.
I still want the final test file to be saved to the local directory, so no changes there!
Related
Am trying to use substring manipulation within a FOR loop and I can't get it to work for love nor money. I've been told that we can't use substring manipulation on a loop variable (%%f etc), so you have to set another variable to equal the loop (set MyVariable=%%f) and then use a substring option to work on this decendent (set MyOtherVar=%MyVariable:~0,-3%). However when echoing these variables only the loop variable is set/non-null.
Here's the code I'm currently using.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET OutPref="373137#"
SET OutSuf1="#Window Clean POD "
SET OutSuf2="#1520755.pdf"
SET MatchStr=#mydomain.com
cd c:\Oscar\Scripts\FileNamer\Inbound\
for /f "tokens=*" %%f in ('dir /b *.pdf') do (
c:\Oscar\Scripts\FileNamer\pdftotext.exe -q %%f
set InPdfVer=%%f
set InTxtVer=%InPdfVer:~0,-3%txt
echo Loop Val= %%f
echo InPdfVer= %InPdfVer%
echo InTxtVer= %InTxtVer%
pause
set InAddLine=findstr %MatchStr% %InTxtVer%
set stemp=%InAddLine%
set pos=0
:loop
set /a pos+=1
echo %stemp%|findstr /b /c:"%MatchStr%" >NUL
if errorlevel 1 (
set stemp=%stemp:~1%
if defined stemp GOTO loop
set pos=0
)
set /a pos-=3
call set StoreNo=%InAddLine:~%pos%,-25%
call:getvalue C:\Oscar\Scripts\FileNamer\StoreList.inf %StoreNum% StoreName
set OutFile=%OutPerf%%StoreNo%%OutSuf1%%StoreName%%OutSuf2%
move %%f c:\Oscar\Scripts\FileNamer\Outbound\%OutFile%
)
cd c:\Oscar\Scripts\FileNamer\
exit 0
:getvalue
rem This function reads a value from a file and stored it in a variable
rem %1 = name of file to search in
rem %2 = search term to look for
rem %3 = variable to place search result
FOR /F "tokens=1,2* delims==" %%i in ('findstr /b /l /i %~2= %1') DO set %~3=%%~j
goto:eof
Hope this makes sense, can try and explain it. Quite likely the bottom part doesnt work either but didnt get that far!
Thanks for any thoughts either way, as a general overview the script is supposed to take PDF files in the incoming folder, convert them to text, search for an email address in that file, look that email address in an external list and then move the PDF file (renaming the file with an aggreed convention in the process) and then move onto the next file, in a loop, until the end of the matching files.
Kind regards,
Oscar
OK so the rest of it seems to what what it should now but I still can't get this substring to set, I just end up with the whole string in the decendent variable. Here's the new code (please excuse the pauses and echos used for troubleshooting).
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET OutPref=373137#
SET OutSuf1=#Window Clean POD
SET OutSuf2=#1520755.pdf
SET MatchStr=#mydomain.com
cd c:\Oscar\Scripts\FileNamer\Inbound\
for /f "tokens=*" %%f in ('dir /b *.pdf') do (
c:\Oscar\Scripts\FileNamer\pdftotext.exe -q %%f
set InPdfVer=%%f
call set InTxtVer=!InPdfVer:~0,-3!txt
for /f "tokens=*" %%x in ('findstr !MatchStr! !InTxtVer!') do set InAddLine=%%x
call:getpos
echo !pos!
pause
call set StoreNo=!InAddLine:~!pos!,-25!
call:getvalue C:\Oscar\Scripts\FileNamer\StoreList.inf !StoreNum! StoreName
echo OutPerf !OutPref!
echo StoreNo !StoreNo!
echo OutSuf1 !OutSuf1!
echo StoreName !StoreName!
echo Outsuf2 !OutSuf2!
set OutFile=!OutPerf!!StoreNo!!OutSuf1!!StoreName!!OutSuf2!
echo %%f !OutFile!
pause
REM move %%f c:\Oscar\Scripts\FileNamer\Outbound\!OutFile!
)
cd c:\Oscar\Scripts\FileNamer\
exit /b
:getpos
set stemp=!InAddLine!
set pos=0
:loop
set /a pos+=1
echo !stemp!|findstr /b /c:"!MatchStr!" >NUL
if errorlevel 1 (
set stemp=!stemp:~1!
if defined stemp GOTO loop
set pos=0
)
set /a pos-=3
goto:eof
:getvalue
rem This function reads a value from a file and stored it in a variable
rem %1 = name of file to search in
rem %2 = search term to look for
rem %3 = variable to place search result
FOR /F "tokens=1,2* delims==" %%i in ('findstr /b /l /i %~2= %1') DO set %~3=%%~j
goto:eof
Thanks all for your inputs, here's the finished script with a few more updates.
Makes use of pdftotext.exe as part of the freeware xpdf suite (please donate as it's a great utility) and in this case some lookup files that help resolve a site number to its description. In the format of
001=My Town
I totally failed to get a workable way to pad 2 digit site codes with a leading 0 to make all sites 3 digits but ended up doing the same thing with another lookup file!
I hope this is of some use to someone else!
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET OutPref=373137#
SET OutSuf1=#My Text
SET OutSuf2=#1520755.pdf
SET MatchStr=#mydomain.com
SET BaseDir=C:\myfolder\
SET LogFile=C:\myfolder\FileNamer.log
SET InFolder=C:\myfolder\Inbound\
SET OutFolder=C:\myfolder\Outbound\
SET StoreList=C:\myfolder\StoreList.inf
SET StoreNoConv=C:\myfolder\StoreNoConv.inf
echo Starting Run %TIME% %DATE% >> %LogFile%
echo Starting Run %TIME% %DATE%
cd %InFolder%
for /f "tokens=*" %%f in ('dir /b *.pdf') do (
%BaseDir%pdftotext.exe -q %%f
set "InTxtVer=%%~nf.txt"
for /f "tokens=*" %%x in ('findstr !MatchStr! !InTxtVer!') do set InAddLine=%%x
call:getpos
call set StoreNo=%%InAddLine:~!pos!,-25%%
echo Now Renaming Store No !StoreNo!
call:getvalue %StoreList% !StoreNo! StoreName
call:getvalue %StoreNoConv% !StoreNo! ThreeDigitNo
set OutFile=!OutPref!Store!ThreeDigitNo!!OutSuf1!!StoreName!!OutSuf2!
echo %%f moved to !OutFile! >> %LogFile%
move "%%f" "%OutFolder%!OutFile!" >> %LogFile%
del !InTxtVer!
)
cd %BaseDir%
exit /b
:getpos
set stemp=!InAddLine!
set pos=0
:loop
set /a pos+=1
echo !stemp!|findstr /b /c:"!MatchStr!" >NUL
if errorlevel 1 (
set stemp=!stemp:~1!
if defined stemp GOTO loop
set pos=0
)
set /a pos-=4
goto:eof
:getvalue
rem This function reads a value from a file and stores it in a variable
rem %1 = name of file to search in
rem %2 = search term to look for
rem %3 = variable to set search result under
FOR /F "tokens=1,2* delims==" %%i in ('findstr /b /l /i %~2= %1') DO set %~3=%%~j
goto:eof
I have written a batch file which I want to overwrite key strings with strings from another .txt file.
currently it copies the new File.txt file perfectly but does not replace the strings with the strings from OldFile.txt file.
example of strings in File.txt file:
...
# Password
Pword=
# AccountName
Account=
# TownName
Town=
# Postcode
Postcode=
# LocationChangedDate
LocationChanged=
example of strings in OldFile.txt file I want to replace from:
...
# Password
Pword=ABC
# AccountName
Account=123
# TownName
Town=LDN
# Postcode
Postcode=WS77TP
# LocationChangedDate
LocationChanged=01/01/2015
Can someone please point me in the right direction or explain where I have made a mistake?
#echo off
setlocal disableDelayedExpansion
::Variables
set InputFile=F:\EXCHANGE\3\Machine\File.txt
set OutputFile=F:\EXCHANGE\3\File-New.txt
set CopyFile=F:\EXCHANGE\3\OldMachine\OldFile.txt
set _strFindPword=Pword=.*
for /F "delims=" %%A in ('findstr /x "Pword=.*" %CopyFile%') do set _strInsertPword=%%A
echo.%_strInsertPword%
set _strFindAccount=Account=.*
for /F "delims=" %%B in ('findstr /x "Account=.*" %CopyFile%') do set _strInsertAccount=%%B
echo.%_strInsertAccount%
set _strFindTown=Town=.*
for /F "delims=" %%C in ('findstr /x "Town=.*" %CopyFile%') do set _strInsertTown=%%C
echo.%_strInsertTown%
set _strFindLocationChanged=LocationChanged=.*
for /F "delims=" %%D in ('findstr /x "LocationChanged=.*" %CopyFile%') do set _strInsertLocationChanged=%%D
echo.%_strInsertLocationChanged%
set _strFindPostcode=Postcode=.*
for /F "delims=" %%E in ('findstr /x "Postcode=.*" %CopyFile%') do set _strInsertPostcode=%%E
echo.%_strInsertPostcode%
(
for /F "delims=" %%L in ('findstr /n "^" "%InputFile%"') do (
set "line=%%L"
setlocal EnableDelayedExpansion
set "line=!line:*:=!"
if "%%L" equ "_strFindPword" (echo.!_strInsertPword!) else (
if "%%L" equ "%_strFindAccount%" (echo.!_strInsertAccount!) else (
if "%%L" equ "%_strFindTown%" (echo.!_strInsertTown!) else (
if "%%L" equ "%_strFindLocationChanged%" (echo.!_strInsertLocationChanged!) else (
if "%%L" equ "%_strFindPostcode%" (echo.!_strInsertPostcode!) else (echo.!line!)
)
)
)
)
endlocal
)
) > "%OutputFile%"
del %InputFile%
ren %OutputFile% File.txt
pause
I think I finally got it...
What it does:
It goes through the OldFile.txt content, searching for markers, if found they are stored into environment variables to be used in the nest step (e.g. for _PWD marker (variable) which has a value of Pword=, it will create a _PWDCONTENTS variable with the content of Pword=ABC).
It goes through File.txt content, searching for the same markers, if one marker found, the corresponding CONTENTS variable is dumped in the OutFile.txt, else the original line. Because that happens in the inner for loop, I had to add some extra logic (the _WROTE var) to avoid writing the same lines more than once.
Notes:
It is supposed (well, besides doing what it's supposed to) to be "configurable" (the code is complicated, it's heading towards meta :) if you will), meaning that if there are changes between the markers the code shouldn't change (well there would be code changes, but not in the functional part only in variable definitions). Let me detail:
If you no longer need to replace the Town= string, then all you have to do is removing _TOWN from _ALL: set _ALL=_PWD _ACCT _POST _LOC.
The reverse: if you want to add some other tag (let's call it Name), you have to create a new environment variable: set _NAME=Name= and add it to _ALL: set _ALL=_PWD _ACCT _TOWN _POST _LOC _NAME.
As an indirect consequence, I didn't focus on performance, so it might run slow. Anyway I tried to keep the disk accesses (which are painfully slow) to a minimum (one example is when having 2 for loops the one that iterates on a file contents - assuming that each iteration takes a disk access; this might not be true, and Win has IO buffering - it's the outer one).
I "commented" out the last line in the file, to avoid overwriting the original file. If that behavior is needed, simply remove the rem at the beginning.
Here's the batch code:
#echo off
setlocal enabledelayedexpansion
set _INFILE="File.txt"
set _OUTFILE="NewFile.txt"
set _OLDFILE="OldFile.txt"
set _PWD=Pword=
set _ACCT=Account=
set _TOWN=Town=
set _POST=Postcode=
set _LOC=LocationChanged=
set _ALL=_PWD _ACCT _TOWN _POST _LOC
echo Parsing old file contents...
for /f "tokens=*" %%f in ('type !_OLDFILE!') do (
for %%g in (!_ALL!) do (
echo %%f | findstr /b /c:!%%g! 1>nul
if "!errorlevel!" equ "0" (
set %%gCONTENTS=%%f
)
)
)
copy nul %_OUTFILE%
echo Merging the old file contents into the new file...
set _WROTE=0
for /f "tokens=*" %%f in ('findstr /n "^^" !_INFILE!') do (
set _TMPVAR0=%%f
set _TMPVAR0=!_TMPVAR0:*:=!
for %%g in (!_ALL!) do (
echo !_TMPVAR0! | findstr /b /c:!%%g! 1>nul
if "!errorlevel!" equ "0" (
echo.!%%gCONTENTS!>>!_OUTFILE!
set _WROTE=1
)
)
if "!_WROTE!" equ "0" (
echo.!_TMPVAR0!>>!_OUTFILE!
) else (
set _WROTE=0
)
)
rem copy /-y %_OUTFILE% %_INFILE%
#EDIT0: Using #StevoStephenson suggestion (as part of the question snippet), I replaced the (2nd) outer for loop to ('findstr /n "^^" !_INFILE!') in order to include the empty lines, so the 3rd remark no longer applies (deleting). Also did some small changes to allow files that contain SPACE s in their paths.
Maybe it works like this
set CopyFile=oldfile.txt
set InputFile=newfile.txt
set str_search="Pword"
for /f "delims=" %%i in ('findstr %str_search% %copyfile%') do set str_replace=%%i
set str_replace="%str_replace%"
echo %str_search%
echo %str_replace%
pause
CALL :far %InputFile% %str_search% %str_replace%
EXIT /B 0
:far
setlocal enableextensions disabledelayedexpansion
set "search=%2"
set "replace=%3"
::remove quotes
set search=%search:"=%
set replace=%replace:"=%
echo %search%
echo %replace%
set "textFile=%1"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
>>"%textFile%" echo(!line!
endlocal
)
EXIT /B 0
At for /f "delims=" %%i in ('findstr %str_search% %copyfile%') do set str_replace=%%i you write the line with the variable that has the needed info to str_replace.
After that you the program calls an embeded find-and-replace-function (:far) whitch i shemelessly stole from Batch script to find and replace a string in text file without creating an extra output file for storing the modified file
This function finds the string "Pword" and replaces it by the line find in the old file.
Attention:
This doesn't solve your problem completely since your new file has to be s.th like this.
#Password
Pword
so if you loose the = it works otherwise it doesn't. I hope this helps you with your problem.
It's not perfect but this may be okay for you:
#Echo Off
Setlocal EnableExtensions DisableDelayedExpansion
(Set InputFile=F:\EXCHANGE\3\Machine\File.txt)
(Set OutputFile=F:\EXCHANGE\3\File-New.txt)
(Set CopyFile=F:\EXCHANGE\3\OldMachine\OldFile.txt)
For /F "Delims=" %%I In (
'FindStr/B "Pword= Account= Town= LocationChanged= Postcode=" "%CopyFile%"'
) Do Set %%I
(For /F "Tokens=1-2* Delims=]=" %%I In ('Find /V /N ""^<"%InputFile%"') Do (
Echo(%%J|FindStr/B # || (If Defined %%J (Call Echo=%%J=%%%%J%%) Else (
If "%%J" NEq "" (Echo=%%J=%%K) Else (Echo=)))))>%OutputFile%
Timeout -1
EndLocal
Exit/B
I've left the delete and rename for you to add at the end.
This solution should be much faster than the other solutions.
It will also preserve empty lines and lines containing ! and ^.
It only needs one findstr call for collecting the old values for all words.
A second findstr determines all lines (by line number) in the infile which needs an update.
#echo off
setlocal EnableDelayedExpansion
set "_INFILE=File.txt"
set "_OUTFILE=NewFile.txt"
set "_OLDFILE="OldFile.txt"
set "_WORDS=Pword= Account= Town= Postcode= LocationChanged="
REM *** get all values for the key words
for /F "tokens=1,* delims==" %%L in ('findstr "!_WORDS!" "!_OLDFILE!"') do (
for /F %%S in ("%%L") do (
set "word[%%S]=%%M"
)
)
REM *** Find all lines which needs an update
set wordIdx=0
for /F "tokens=1,2,* delims=:= " %%1 in ('findstr /n "!_WORDS!" "!_INFILE!"') do (
set "lines[!wordIdx!].line=%%1"
set "lines[!wordIdx!].word=%%2"
set "replace=!word[%%2]!"
set "lines[!wordIdx!].replace=!replace!"
set /a wordIdx+=1
)
REM *** copy the infile to the outfile
REM *** Replace only the lines which are marked by line numbers
echo Parsing old file contents...
set nextWordIdx=0
set /a searchLine=lines[!nextWordIdx!].line
set lineNo=0
setlocal DisableDelayedExpansion
(
for /f "tokens=*" %%L in ('findstr /n "^" "%_INFILE%"') do (
set "line=%%L"
set /a lineNo+=1
setlocal EnableDelayedExpansion
set "line=!line:*:=!"
if !lineNo! equ !searchLine! (
(echo(!line!!lines[0].replace!)
set /a nextWordIdx+=1
for /F %%R in ("!nextWordIdx!") do (
endlocal
set /a nextWordIdx=%%R
set /a searchLine=lines[%%R].line
)
) ELSE (
(echo(!line!)
endlocal
)
)
) > "!_OUTFILE!"
So in Windows Explorer, I have these files sorted like this:
I have this script to remove the brackets and one zero, and in case the trailing number is greater than or equal to 10, to remove two zeroes:
cd C:\folder
setlocal enabledelayedexpansion
SET /A COUNT=0
for %%a in (*.jpg) do (
SET /A COUNT+=1
ECHO !COUNT!
set f=%%a
IF !COUNT! GTR 9 (
set f=!f:^00 (=!
) ELSE (
set f=!f:^0 (=!
)
set f=!f:^)=!
ren "%%a" "!f!"
)
pause
However, once I run the code, I get this result:
So the batch file isn't going through the files "intuitively" like Windows Explorer shows them. Is there any way to change this? Or is there a better way to rename these files altogether?
This uses a different approach:
#echo off
cd C:\folder
setlocal enabledelayedexpansion
SET /A COUNT=0, REMOVE=2
for /F "delims=(" %%a in ('dir /B *.jpg') do (
SET /A COUNT+=1
ECHO !COUNT!
set "f=%%a"
IF !COUNT! EQU 10 SET "REMOVE=3"
for /F %%r in ("!REMOVE!") do set "f=!f:~0,-%%r!"
ren "%%a" "!f!!COUNT!.jpg"
)
pause
Here is a method that does not depend on the sort order used by the file system, preserving the numbers as occurring in the original file names.
For each file name (for instance, test_this_01 SELR_Opening_00000 (1).jpg), the portion after the last under-score _ is retrieved (00000 (1)). Then the parentheses and the space are removed and then the length is trimmed to five characters (00001). This string replaces the original one in the file name finally (test_this_01 SELR_Opening_00001.jpg); the file name must not contain the replaced portion (00000 (1)) multiple times (hence file names like this should not occur: test_this_00000 (1) SELR_Opening_00000 (1).jpg):
#echo off
setlocal DisableDelayedExpansion
rem // Define constants here:
set "LOCATION=."
set "PATTERN=*_* (*).jpg"
set /A "DIGITS=5"
pushd "%LOCATION%" || exit /B 1
for /F "usebackq eol=| delims=" %%F in (`
dir /B /A:-D /O:D /T:C "%PATTERN%"
`) do (
set "FILE=%%F"
setlocal EnableDelayedExpansion
set "LAST="
for %%I in ("!FILE:_=","!") do (
set "LAST=%%~nI" & set "FEXT=%%~xI"
set "FNEW=!FILE:%%~I=!"
)
set "LAST=!LAST:(=!" & set "LAST=!LAST:)=!"
set "LAST=!LAST: =!" & set "LAST=!LAST:~-5!"
ECHO ren "!FILE!" "!FNEW!!LAST!!FEXT!"
endlocal
)
popd
endlocal
exit /B
Adapt the directory location and the file search pattern in the top section of the script as you like.
After having tested, remove the upper-case ECHO command in order to actually rename files.
I have a few directories, named "A", "B", "C", and so on. Each has some files in it. I like to rename files in each directory using directory name plus an index number starting with 1 in each directory, with left-zero padded to the width of 3. For example:
Sub directory A has 3 files, and they'll be renamed as:
A_001.dat
A_002.dat
A_003.dat
Sub directory B has 2 files, and they should be renamed as:
B_001.dat
B_002.dat
and so on. These files will be moved to the main directory. I have the following batch file, but I can't seem to increment the number. Please help.
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=DAT
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
set i=1
for /f "delims=" %%b in ("%%~dpa\.") do (
set pad=00!i!
set str=!pad:~-3!
echo move /b "%%a" "%HomeFolder%\%%~nxb_!str!.%NewExt%"
set /A i=!i!+1
)
)
endlocal
pause
And the correct answer is:
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=TIF
set i=1
set Folder=
set LastFolder=
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
for /f "delims=" %%b in ("%%~dpa\.") do (
set Folder=%%~nxb
if NOT !Folder!==!LastFolder! (set /A i=1)
set LastFolder=!Folder!
set pad=00!i!
set str=!pad:~-3!
copy /b "%%a" "%HomeFolder%\%%~nxb_!str!.%NewExt%"
Set /A i+=1
)
)
endlocal
In a loop or parenthetical expression you need to use a delayed expansion
set /a variable=!variable!+1
But you need to activate this feature with setlocal ENABLEDELAYEDEXPANSION and reset it with a matching endlocal
Try the following:
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=DAT
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
set i=1
for /f "delims=" %%b in ("%%~dpa\.") do (
set pad=00%i%
set str=%pad:~-3%
echo move /b "%%a" "%HomeFolder%\%%~nxb_%str%.%NewExt%"
set /A i+=1
)
)
endlocal
pause
#echo off
:: By Elektro H#cker
Setlocal enabledelayedexpansion
set "OldExt=TXT"
set "NewExt=DAT"
FOR /R %%# in (*%OldExt%) DO (
REM Sets the directory of the file
Set "Directory=%%~dp#"
REM Cuts the directory name to obtain the last folder name
Set "Directory=!Directory:~0,-1!"
For /L %%X in (0,1,50) DO (Call Set "Directory=!Directory:*\=!")
REM Check if this directory is the same of the last accesed directory to reset the counter or not
Echo "!Directory!"|FINDSTR "^\"!LastDirectory!\"$" >NUL && (Set /A "Count+=1") || (Set /A "Count=1")
REM Check if the number incrementation have 1-3 digits and copies the file
Call Echo !COUNT!|FINDSTR "^[0-9]$" >NUL && (Call Copy "%%#" ".\!Directory!_00!COUNT!.%NewExt%")
Call Echo !COUNT!|FINDSTR "^[0-9].$" >NUL && (Call Copy "%%#" ".\!Directory!_0!COUNT!.%NewExt%" )
Call Echo !COUNT!|FINDSTR "^[0-9]..+$" >NUL && (Call Copy "%%#" ".\!Directory!_!COUNT!.%NewExt%" )
REM Sets the last accesed directory
Call Set "LastDirectory=!Directory!"
)
Pause&exit
3 subdirs named "A" "B" and "C", 3 files inside of each subdir, the output result is:
a_001.DAT
a_002.DAT
a_003.DAT
b_001.DAT
b_002.DAT
b_003.DAT
c_001.DAT
c_002.DAT
c_003.DAT
Here is the working script for whoever wants to do the same thing:
#echo off
set HomeFolder=%CD%
set OldExt=TXT
set NewExt=DAT
set i=1
set Folder=
set LastFolder=
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('dir *.%OldExt% /b /s') do (
for /f "delims=" %%b in ("%%~dpa\.") do (
set Folder=%%~nxb
if NOT !Folder!==!LastFolder! (set /A i=1)
set LastFolder=!Folder!
set pad=00!i!
set str=!pad:~-3!
copy /b "%%a" "%HomeFolder%\%%~nxb_!str!.%NewExt%"
Set /A i+=1
)
)
endlocal
I am trying to modify a batch file created by somebody else, to add leading zeros depending on the number found on line 4 of the file. The actual filename is a concatenation of the name found on line 3, and the numbers on line 4. So if the first few lines are as follows:
3.1.19
-1
TEST
560
The file name would be v_TEST00560.TXT. As you can see, the total number of digits in the file name should be 5. If the number which appears on line 4 is 8 (see below), then:
3.1.19
-1
TEST
8
The file name will be v_TEST00008.txt.
The file I have is as follows:
#Echo Off
Setlocal EnableDelayedExpansion
REM File: rename5.bat
REM The script will look for and parse one (or more) input files
REM Input files can containrecords for one or more vessels.
REM This script assumes that each record starts with the "3.1.19" string.
REM %%%%%%%%%%%%%%%%%%%%%%% Configuration Section %%%%%%%%%%%%%%%%%%%%%%%
SET INPUT_DIR=C:\Files\RenameFileName\Input
SET OUTPUT_DIR=C:\Files\RenameFileName\Output
SET ARCHIVE_DIR=C:\Files\RenameFileName\Archive
SET TEMP_DIR=C:\Files\RenameFileName\tmp
SET INPUT_FILENAME=INTERFACE.TXT
SET REC=3.1.19
REM %%%%%%%%%%%%%%%%%%%%%%%%%%%% Checking Section %%%%%%%%%%%%%%%%%%%%%%%%%%%%
FOR /F "usebackq tokens=* eol= delims= " %%d IN (`date /t`) do SET RUNDATE=%%d
echo [%RUNDATE% %TIME%] Script starting...
IF NOT EXIST %INPUT_DIR% (
SET MESSAGE=Input directory not found.
goto END
)
IF NOT EXIST %OUTPUT_DIR% (
SET MESSAGE=Output directory not found.
goto END
)
IF NOT EXIST %ARCHIVE_DIR% (
SET MESSAGE=Archive directory not found.
goto END
)
IF NOT EXIST %TEMP_DIR% (
echo Temporary directory does not exit.
echo Creating %TEMP_DIR%
mkdir %TEMP_DIR%
)
REM %%%%%%%%%%%%%%%%%%%%%%%%% Main Processing %%%%%%%%%%%%%%%%%%%%%%%%%
dir %INPUT_DIR%\%INPUT_FILENAME% 1>NUL 2>NUL
IF %ERRORLEVEL% EQU 1 (
SET MESSAGE=Input files not present.
goto END
)
FOR /F "usebackq tokens=* eol= delims= " %%d IN (`date /t`) do SET RUNDATE=%%d
echo [%RUNDATE% %TIME%] Input files found. Start Processing...
FOR /F "usebackq" %%I IN (`dir /b %INPUT_DIR%\%INPUT_FILENAME%`) DO (
SET INPUT_FILE=!INPUT_DIR!\%%I
echo READING Input file: !INPUT_FILE!
SET N=
FOR /F "tokens=* eol= delims= " %%A IN (!INPUT_FILE!) Do (
set LINE=%%A
set LINE2=!LINE:~0,6!
if !LINE2! EQU !REC! (
SET /A N+=1
echo Creating temp file !TEMP_DIR!\!N!.tmp
)
echo !LINE! >> !TEMP_DIR!\!N!.tmp
)
FOR /F "usebackq" %%Y in (`dir /b !TEMP_DIR!\*.tmp`) DO (
SET TEMPFILE=!TEMP_DIR!\%%Y
SET N=
FOR /F %%A IN (!TEMPFILE!) DO (
SET /A N+=1
IF !N! EQU 3 SET S=%%A
IF !N! EQU 4 SET T=%%A
)
SET S=!S:~0,10!
SET T=!T:~0,10!
echo CREATING Output File: %OUTPUT_DIR%\V_!S!00!T!.TXT
MOVE !TEMPFILE! %OUTPUT_DIR%\V_!S!00!T!.TXT
)
)
REM %%%%%%%%%%%%%%%%%%%%%%%%% Archiving Section %%%%%%%%%%%%%%%%%%%%%%%%%
FOR /F "usebackq" %%t IN (`cscript "%~dp0timestamp.vbs" //Nologo`) do SET TIMESTAMP=%%t
FOR /F "usebackq" %%I IN (`dir /b %INPUT_DIR%\%INPUT_FILENAME%`) DO (
echo ARCHIVING Input file %%I to %ARCHIVE_DIR%
rem COPY !INPUT_DIR!\%%I !ARCHIVE_DIR!\%%I.!TIMESTAMP!
MOVE !INPUT_DIR!\%%I !ARCHIVE_DIR!\%%I.!TIMESTAMP!
)
REM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FOR /F "usebackq tokens=* eol= delims= " %%d IN (`date /t`) do SET RUNDATE=%%d
SET MESSAGE=[%RUNDATE% %TIME%] Processing Done.
:END
echo %MESSAGE%
FOR /F "usebackq tokens=* eol= delims= " %%d IN (`date /t`) do SET RUNDATE=%%d
echo [%RUNDATE% %TIME%] Script finished.
As you can see, its quite sophisticated, and I have no idea how to make these changes myself. The BAT runs perfectly, but the number of zeroes if fixed, and not generated depending on the number of digits already present. Any help appreciate
I'm not about to read all of your code, but I use this for padding zeros.
The first line is whetever number you read from your file.
The second line pads more than enough zeros to the start of the variable.
The third line cuts off all but the last five characters from the variable.
Set Number=123
Set Number=00000%Number%
Set Number=%Number:~-5%