Not sure this is possible with only a batch file.
I have a file named BaseFile.7z location is E:\Backup\C Drive Zip\BaseFile.7z
Is it possible to create a batch command that renames the file with its creation date? For example BaseFile - 02-19-2015.7z
I currently have a command that renames the file with the current date which I pasted below for reference, but thats not exactly what I'm looking for. I need creation date.
RENAME "E:\Backup\C Drive Zip\Jaipur.txt" "BaseFile - %date:/=-%.txt"
#ECHO OFF
SETLOCAL
SET "filename=U:\sourcedir\zzz.zzz"
IF NOT EXIST "%filename%" ECHO "%filename%" NOT found&GOTO :eof
SET "datepart="
FOR /f "tokens=1-3delims=/-:" %%a IN ('dir /tc "%filename%"') DO IF "%%c" neq "" SET "datepart=%%a-%%b-%%c"
FOR /f %%a IN ("%filename%") DO FOR /f %%d IN ("%datepart%") DO ECHO(REN "%%a" - "%%~na %%d%%~xa"
GOTO :EOF
The required REN command is merely ECHOed for testing purposes. After you've verified that the command is correct, change ECHO(REN to REN to actually rename the file.
Note that there is general sloppiness in the use of date-references. There are three dates on each file - actual create date (use /tc), last access (/ta) and last-written (/tw).
The process locates the file, then reads a dir listing with the appropriate date selected. The only or last line in the listing that will contain a third non-empty token is the date/time of the file in question, so datepart will acquire yyyy-mm-dd hh
the for/f %%a then applies the full filename to %%a ready for partitionig into its components and the for/f %%d assigns the first token from datepart (ie up to the space) into %%d.
Bang the components together, and the resut is reported...
Related
I have a custom service that automatically generates files every 60 mins into a particular directory with part of the filename incrementing numerically, Eg:
File_00004.job
File_00003.job
File_00002.job
File_00001.job
Currently I have an issue where on occasion a file isn't generated, which results in gaps in the file sequence. This issue then causes a number of issues if not identified ASAP.
I'd like a batch file to identify if I have a gap in the file name sequence.
Tried looking for solutions from existing posts, but haven't found something that fits, so apologies if this has been covered elsewhere.
#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\t w o"
SET "mask=file_??????.job"
SET "lowest="
SET "highest="
FOR /f "delims=" %%a IN (
'dir /b /a-d /on "%sourcedir%\%mask%" '
) DO (
IF NOT DEFINED lowest SET "lowest=%%~na"
SET "highest=%%~na"
)
SET "lowest=%lowest:*_=1%"
SET "highest=%highest:*_=1%"
ECHO checking range %lowest:~1% to %highest:~1%
:: See whether an entry in the range is missing; report&create an empty file if so.
FOR /L %%a IN (%lowest%,1,%highest%) DO SET "name=%%a"&SET "name=file_!name:~1!.job"&IF NOT EXIST "%sourcedir%\!name!" echo !name! missing&(copy nul "%sourcedir%\!name!" >nul)
GOTO :EOF
Alternative structure for the for /L loop:
FOR /L %%a IN (%lowest%,1,%highest%) DO (
SET "name=%%a"
SET "name=file_!name:~1!.job"
IF NOT EXIST "%sourcedir%\!name!" (
echo !name! missing
copy nul "%sourcedir%\!name!" >nul
copy "d:\path to\template.file" "wherever\!name!" >nul
copy "d:\path to\template.file" "anotherplace\!name!" >nul
echo Batch is fun and powerful
copy "d:\path to\template.file" "a third place\!name!" >nul
)
)
The critical point is the positioning of the ( - must be directly after and on the same line as do or else or the logical comparison clause of if and must be matched by a ) (which doesn't need to be on its own line - I find it easier that way, to align indentation.) )s that are not intended to close a block need to be escaped with ^, thus: ^)
I’m trying to make a script that removes the ” – Shortcut” from shortcut names and have discovered an odd phenomenon, if the name is under 6 characters not including the “ – Shortcut.lnk” the loop goes through an extra cycle for that file and makes its name blank. However this only applies to the first file not any file after the first.
So if we have two lnk files one is “12345 – Shortcut.lnk” and the other is “C1 – Shortcut.lnk” the output is a blank lnk file and a “C1.lnk”
But “123456 – Shortcut.lnk” and “C1 – Shortcut.lnk” gives “123456.lnk” and “C1.lnk” (the way its suppose to work)
“x1 – Shortcut.lnk” and “c1 – Shortuct.lnk” gives a blank lnk file and and “x1.lnk”
Here is the script I’m using
#echo off
setlocal enabledelayedexpansion
for %%i in ("*.lnk") do (
set CurrentFile=%%i
set NewName=!CurrentFile:~0,-15!.lnk
ren "%%i" "!NewName!"
)
pause
What is happening is that when the file is renamed, the new name is placed later in the directory than the old name, so the for finds the filename again as it processes the names mechanically as it encounters them.
Three solutions
You could change your mask to
for %%i in ("* - shortcut.lnk") do (
You could change your processing to ensure that the shortcut text is still there before renaming by gating the rename
if /i "!CurrentFile:~0,-15!"=="- shortcut.lnk" (
(
set NewName=!CurrentFile:~0,-15!.lnk
ren "%%i" "!NewName!"
)
Or you use for /f which builds a list in memory, then processes the list (hence only the "old" names are present)
for /f "delims=" %%i in ('dir /b/a-d "*.lnk" ') do (
or preferably
for /f "delims=" %%i in ('dir /b/a-d "* - shortcut.lnk" ') do (
The second is preferable since the dir command will only select names ending appropriately, so the process can be run repeatedly despite having rnamed files on a prior run.
Since you're trying to delete a specific string (rather than generally shorten the filename), you're probably safer using the substitution operator to explicitly remove - Shortcut if present:
#echo off
setlocal enabledelayedexpansion
for %%i in ("*.lnk") do (
set "CurrentFile=%%i"
set "NewName=!CurrentFile: - Shortcut=!"
ren "%%i" "!NewName!"
)
pause
I'm looking for a way to copy from specified line to the EOF?
I have two or more text.log which are filled from time to time and I need to append all these data to one textall.log but remembering the last line in text.log because otherwise are copied again all data in textall.log.
So - it would appear you wish to accumulate all of the updates to *.log into textall.log
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "history=q28129095.history"
PUSHD "%sourcedir%"
:: force history file to eist
ECHO(>>"%history%"
FOR /f "tokens=1*delims=" %%a IN (
'dir /b /a-d "*.log" '
) DO IF /i "%%a" neq "textall.log" (
SET "filename=%%a"
REM find lines in target logfile
FOR /f "tokens=2delims=:" %%q IN ('find /c /v "" "%%a"') DO SET /a lines=%%q
REM locate record of this file in history
SET "hist="
FOR /f "usebackqtokens=1,2delims=:" %%q IN ("%history%") DO IF "%%q"=="%%a" SET "hist=skip=%%r"
REM append new lines to textall.log
CALL :addlines
)
popd
GOTO :EOF
:addlines
FOR /f "usebackq %hist% delims=" %%q IN ("%filename%") DO >>textall.log ECHO(%%q
:: Now maintain the history file
(FOR /f "delims=" %%r IN ('FINDSTR /V /B /L /c:"%filename%" "%history%"') DO echo(%%r)>"%history%.temp"
:: record new start-line
>>"%history%.temp" ECHO(%filename%:%lines%
MOVE /y "%history%.temp" "%history%" >nul
GOTO :eof
You would need to change the setting of sourcedir to suit your circumstances.
For lack of further information, I've assumed testxall.log is in the same directory as all of the logfiles.
You would need to set history to a filename (possibly including a pathname) to suit you. This file retains a record of how far has already been recorded to the accumulated log.
You need to consider what would happen if your logfiles are purged - you'd need to maintain the history file manually.
Also consider that there's noindication of the source log in the accumulated.
And empty lines will be expunged.
Response to problem report
I can't reproduce your symptoms.
The echo keyword should not appear in the history file. Note that the coding is very precise - echo( not echo (. Although traditionally the character following echo is a space, there is a set of characters which may succeed the o and produce virtually the same result. Of these, ( is paricularly useful because echo %something% where something is undefined will report echo is on/off but echo(%something% where something is undefined will produce a new line
This is the result I obtained by running the routine twice; the first time with 4 lines in each of x1..5.log and the second with x5.log deleted and the others with 6 lines:
X5.log:4
X1.log:6
X2.log:6
X3.log:6
X4.log:6
What should happen with regard to the history file is:
An empty line is added at the start by ECHO(>>"%history%"
This should simply ensure the file exists so findstr has nothing to complain about
for each logfile, hist is set to nothing then the history file is examined and tokenised. The name is assigned to %%q and the previous-linecount to %%r. If the filename matches then the hist string is set to skip=(previous-linecount)
within the :addlines procedure, the findstr command allows through all of the lines which do not match (/v) the literal (/L) of the filename (/c:"string"), which should remove any existing record for the file %filename%. This is mechanically read by a for/f command assigning the entire line to %%r (because of the delims= - and this also removes empty lines.
There is a little technique however that you may have "corrected." The echo( I've already covered. As I've coded it, the line then reads
(for...etc...echo(%%r)>"temporaryfilename"
The parentheses here are important as they serve to output the entire response from for into a new file. The name and linecount for the log file are then appended to this tempfile and it's renamed for the next cycle.
I've modified the findstr here by adding in a /b switch to cause the filename match to be applied at the beginning of the line. In this way, "X2.log" won't delete the record for "anotherlogx2.log" by matching the x2.log part.
If you have further trouble, please edit your original question to include formatted data if required. As you've seen, using comments doesn't make the situation clear...
I have a folder that gets a new file added everyday to the folder with the same file name but incremental extension such as .001, .002, .003, etc. However, if there's no file within the folder it starts at .001 again.
The problem is they are all named the same and if I move them to another folder to archive them it would just overwrite the same file over and over again. I could create a folder each day with the date with only one file in it, but that seems a bit redundant.
Is there a way to look at the create date of each file and rename it to the create date?
I've gotten this far, but it looks like for this situation I have to use a static file name, how to loop through the entire directory?
SET filename = C:\test.001
FOR %%f IN (%filename%) DO SET filedatetime=%%~tf
rename c:\test.001 C:\test_%filedatetime%.txt
move C:\*.txt C:\archive\
this provides the correct sort order:
#echo off &setlocal disableDelayedExpansion
set "startfolder=%userprofile%\test"
cd /d "%startfolder%"
for %%a in (*) do (
for /f "delims=." %%b in ('wmic datafile where "name='%startfolder:\=\\%\\%%~a'" get lastmodified^|find "."') do (
echo(ren "%startfolder%\%%~a" "%%~b.txt"
)
)
Remove echo to get it working.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "targetdir=c:\sourcedir"
SET "destdir=c:\destdir"
PUSHD "%targetdir%"
FOR %%a IN (*.*) DO (
SET "timestamp=%%~ta"
SET "timestamp=!timestamp:/=_!
SET "timestamp=!timestamp::=_!
SET "timestamp=!timestamp:.=_!
SET "timestamp=!timestamp:,=_!
SET "timestamp=!timestamp: =_!
ECHO MOVE "%%a" "%destdir%\%%~na.!timestamp!"
)
GOTO :EOF
This should work with any file in the nominated target directory where the name does not include ! or ^.
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)
The gymnastics around timestamp are intende to replace /: with _ since these are illegal filename characters. Space., are similarly replaced - they're legal but often painful.
If you want the destination filename to be name.003.timestamp, remove the ~na from the destination name.
Try like this :
SET $path=The_path_who_contain_the_FILES
FOR /F "DELIMS=" %%f IN ('dir "%$path%" /a-d/b') DO (
SET filedatetime=%%~tf
move "%%~dpnxf" "C:\archive\test_%filedatetime%.txt")
Happy Friday Think-Tank!
I need some assistance with a Batch .BAT script. Specifically I need help with some "IF statement syntax"
I have a script that is renaming files. There are two files, one ending in four digits and the other ending in five digits. The files will be renamed with variables I have already pre-set earlier within my script.
So here is a scenario: We have two files in a directory located at
c:\Users\username\Desktop\test-dir
There are two files within test-dir:
file1.12345
file2.1234
A four digit ending is one variable type (VAR1), whereas a file ending in five digits is another variable type (VAR2).
I need an if statement to:
a) read all the files(s) with the chosen directory (without using a wildcard if possible).
b) determine based on the number of digits after the "." which variable to use.
c) once making that determination rename the file with the appropriate variables.
The final re-naming convention is as so: yyyymmddtype.1234/12345
So basically it would use the datestamp variable I already created, the type variable I already created to be injected by the if statement, and append with the original ending digits of the file.
I know this seems like a lot, but I am more so a bash script guy. I have all the elements in place, I just need the if statement and what feels like a for loop of some kind to tie it all together.
Any help would be great!
Thank you!
Sorry, not the option you where asking for. Instead of iterating over the full list checking each file for extension conformance, iterate over a list of patterns that will filter file list, renaming matching files with the asociated "type"
for %%v will iterate over variable list, for %%a will split the content of the variable in pattern and type, for %%f will generate the file list, filter with findstr using the retrieved pattern and rename matching files with the corresponding "type"
Rename command is preceded with a echo to output commands to console. If the output is correct, remove the echo to rename the files.
#echo off
rem Variables defined elsewhere
set "folder=c:\somewhere"
set "timestamp=yyyymmdd"
rem Rename pattern variables in the form pattern;type
set "var1=\.....$;type1"
set "var2=\......$;type2"
set "var1=\.[^.][^.][^.][^.]$;type1"
set "var2=\.[^.][^.][^.][^.][^.]$;type2"
setlocal enableextensions disabledelayedexpansion
for %%v in ("%var1%" "%var2%") do for /f "tokens=1,* delims=;" %%a in ("%%~v") do (
for /f "tokens=*" %%f in ('dir /a-d /b "%folder%" ^| findstr /r /c:"%%~a"') do (
echo ren "%folder%\%%~f" "%timestamp%%%~b%%~xf"
)
)
endlocal
#ECHO OFF &SETLOCAL
set "yyyymmdd=yyyymmdd"
set "VAR1=VAR1"
set "VAR2=VAR2"
for /f "delims=" %%a in ('dir /b /a-d^|findstr /re ".*\....."') do echo(ren "%%~a" "%yyyymmdd%%VAR1%%%~xa"
for /f "delims=" %%a in ('dir /b /a-d^|findstr /re ".*\......"') do echo(ren "%%~a" "%yyyymmdd%%VAR2%%%~xa"
remove echo( to get it working.
If I understand you then this will rename the two files using preset variables for each one:
for %%a in ("%userprofile%\Desktop\test-dir\*") do (
if "%%~xa"==".12345" ren "%%a" "%variableA%-%variableB%%%~xa"
) else (
ren "%%a" "%variableC%-%variableD%%%~xa"
)
)