I’m using the following script to add a revision number to a .stp file. For example: ABS0012033.stp to ABS0012033_rev001.stp. This is working well.
Now I have some files that end with _asm.stp, for example, ABS0012033_asm.stp. How do I need to modify the script that it works for both file types?
Some additional information: There is only one .stp file to be renamed per time and then the .stp file will be moved to another folder. The text file which contains the revision number is temporary and will be deleted after renaming the .stp file.
The current script does remove the last 4 characters from the filename and stores the filename in variable str1. Then it renames the filename with str1 + revision number.
for /F "usebackq tokens=2" %%a IN (`findstr REVISION C:\PUBLISH_WORKSPACE\*.txt`) do (
SET Rev=%%a)
FOR %%S IN ( c:\publish_workspace\*.STP) DO (SET FILE=%%S)
set str1=%file:~21,-4%
ren %file% %str1%_rev%REV%.stp
EXIT
I have tried to implement an IF function in the following script, but it doesn’t work. It doesn’t write str1 when renaming the filename. Any ideas what the problem could be?
for /F "usebackq tokens=2" %%a IN (`findstr REVISION C:\PUBLISH_WORKSPACE\*.txt`) do (
SET Rev=%%a)
FOR %%S IN ( c:\publish_workspace\*.STP) DO (SET FILE=%%S)
echo.%FILE%|findstr /C:"_asm" >nul 2>&1
if not errorlevel 1 (
set str1=%file:~21,-8%
ren %file% %str1%_rev%REV%.stp
) else (
set str1=%file:~21,-4%
ren %file% %str1%_rex%REV%.stp
)
pause
move c:\publish_workspace\*.stp c:\publish_workspace\stp
del c:\publish_workspace\*.txt
EXIT
Sorry, I'm not sure to understand the problem. What about this?
set Rev=ren001
ren ABS???????_asm.stp ABS???????_%Rev%.stp
This answer makes assumptions, those assumptions could have been resolved had you responded to my comment one day ago.
#Echo Off & SetLocal EnableExtensions
PushD "C:\Publish_Workspace" 2>NUL && (Set "Rev=") || GoTo :EOF
For /F "Tokens=1,* Delims=:" %%G In ('%SystemRoot%\System32\findstr.exe "REVISION" "*.txt"') Do Set "Rev=%%H"
If Not Defined Rev GoTo :EOF
For /F Delims^=^ EOL^= %%G In ('Set "PathExt=" ^& %SystemRoot%\System32\where.exe ".":"*.stp" 2^>NUL') Do For /F Delims^=_^ EOL^= %%H In ("%%~nG") Do Ren "%%G" "%%H_rev%Rev:* =%%%~xG"
I am not a tutor, and will not be providing additional explanation, other than to refer you to my comments, and the built-in help information for each command, (commandName /?).
Related
I am new to writing batch programs. I have thousands of folders that have a leading space character in their name and I need to remove the space. By perusing the Stack Overflow site, I have put together some code that performs as expected in WinXP, but NOT on my Win10 system.
#echo off
for /d %%A in (" *") do #for /f "tokens=*" %%B in ("%%A") do #ren "%%A" "%%B"
The code snippet above works just fine in WinXP. For example, a folder may be named " L700" but the name gets correctly changed to "L700" after running the code. However, on my Win10 system, the above code doesn't change anything with the filename.
Full code is below:
#echo off
rem Prepare environment
setlocal enableextensions disabledelayedexpansion
rem configure where to start
set "root=C:\Test"
rem For each file under root that match indicated pattern
for /r "%root%" %%f in (*,*,*.xlsm) do (
rem Split the file name in tokens using the comma as delimiter
for /f "tokens=2 delims=," %%p in ("%%~nf") do (
rem Test if the file is in the correct place
for %%d in ("%%~dpf.") do if /i not "%%~p"=="%%~nd" (
rem if it is not, move it where it should be
if not exist "%%~dpf\%%~p" md "%%~dpf\%%~p"
move "%%~ff" "%%~dpf\%%~p"
)
)
)
rem line below removes space from beginning of folder name
for /d %%A in (" *") do #for /f "tokens=*" %%B in ("%%A") do #ren "%%A" "%%B"
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
FOR /d %%a IN ("%sourcedir%\ *") DO (
ECHO "%%a"
for /f "tokens=*" %%b in ("%%~nxa") do ECHO ren "%%a" "%%~nxb"
)
GOTO :EOF
ren command has been disarmed and is simply echoed for safety until script action is verified.
I've no access to an XP system, but I'm surprised it worked on XP. The issue is that %%a contains the full path so you need to select only the name and extension for the rename and the leading-space-suppression mechanism.
Trying to create a script that will take the third token of a file name, create a folder based on it and move the associated file to that folder.
Have got this so far:
#ECHO OFF
SETLOCAL
SET "sourcedir=D:\Sourcedir"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3,4 delims=" %%a IN (
'dir /b /a-d "*.pdf"'
) DO (
ECHO MD %%c
ECHO MOVE "%%a %%b %%c %%d" .\%%c\
)
POPD
GOTO :EOF
Only problem is the folder being created is including the file extension where as I just need the folder to be named the third token.
Example file name:
"File Number 10.pdf
Expected folder name:
10
Thanks
Why did you use delims=? This will remove delimiter, and take whole line to %%a.
Try this:
#ECHO OFF
SETLOCAL
SET "sourcedir=D:\Sourcedir"
PUSHD %sourcedir%
FOR /f "tokens=1,2,3" %%a IN (
'dir /b /a-d "*.pdf"'
) DO (
ECHO MD %%~nc
ECHO MOVE "%%a %%b %%c" .\%%~nc\
)
POPD
GOTO :EOF
When no delims= set, it will use space. So %%c will be 10.pdf, ~n is to extract its name part.
This is based on your question, which you can concatenate %%a %%b %%c together with spaces, then it's simple.
If your filenames are more complicated, then an inner for loop is better.
-- Which another question already gave a great solution.
Here's an alternative, which will just use the last space delimited string/number, regardless of how many there are, (if there are none it will use the whole filename)!
#Echo Off
For %%A In ("D:\Sourcedir\*.pdf") Do Call :L "%%A"
Exit /B
:L
Set "F=%~n1"
Set "F=%F: ="&Set "F=%"
If Not Exist "%~dp1%F%\" MD "%~dp1%F%"
Move /Y %1 "%~dp1%F%"
And if you wanted to move only those which have at least one space, you can include that inside the For parentheses.
#Echo Off
For %%A In ("D:\Sourcedir\* *.pdf") Do Call :L "%%A"
Exit /B
:L
Set "F=%~n1"
Set "F=%F: ="&Set "F=%"
If Not Exist "%~dp1%F%\" MD "%~dp1%F%"
Move /Y %1 "%~dp1%F%"
You can run 2 for loops get the full name in the first, then split the name in the second loop, get the 3rd token, create the directory and then copy the actual file name from the first loop.
This way you do not need to try and patch the name together again, I know it works, but it is ugly and not prefered:
#echo off
setlocal enabledelayedexpansion
set "sourcedir=D:\Sourcedir"
pushd %sourcedir%
for %%a in (*.pdf) do (
set "var=%%a"
for /f "tokens=3" %%i in ("!var!") do (
echo md "%%~ni"
echo move "%%~a" "%%~ni"
)
)
popd
goto EOF
For more information on these commands, see help for each from cmd.exe i.e
for /?
set /?
setlocal /?
set and setlocal has very specific information regarding delayed expansion.
Scenario:
We have multiple releases of a product, and for each release, a folder is created in the main folder. A help file is modified in various releases. I have all the help file names listed in a text file.
I need a script to:
Take each file name from the filenames.txt file
Search for the file by that name in the entire directory (in all releases)
Find the latest file
Copy it to a specified folder
I took help from the various pieces of code I found on Stack Overflow, and combined them to get this code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
echo.
FOR /F "usebackq delims=" %%a in ("filenames.txt") do (
SET "x=%%a"
ECHO '!x!'
SET FFPath=C:\SVN\nlbavwdocsvn\rep_doc_erpln\trunk\ERPLN
SET NewPath=C:\Lavanya\extracted
SET NewestDate=20160824
ECHO Recursively searching %FFPath%
FOR /F %%I in ('DIR %FFPath%\ !x! /a:-d /s /b') DO (
SET FullDate=%%~tI
ECHO %FFPath%
REM Set CurrDate to yyyymmdd format. Note: Will fail if regional settings changed.
SET CurrDate=!FullDate:~6,4!!FullDate:~0,2!!FullDate:~3,2!
If !CurrDate! gtr !NewestDate! (
SET NewestDate=!CurrDate!
SET NewestFile=%%~fI )
ECHO Copying %NewestFile% to %NewPath%
ECHO.
COPY /Y "%NewestFile%" "%NewPath%"
ECHO.
)
)
PAUSE
This code is not working. And I am unable to figure out the error.
Here is a script to search for the most recently modified file, using the wmic command to retrieve the last modification date/time in a locale-independent manner (e. g., 20160824115500.000000+060).
So for every file name read from the list file .\filenames.txt, the directory tree routed at directory C:\SVN\nlbavwdocsvn\rep_doc_erpln\trunk\ERPLN is searched for matching files recursively, and the respective modify date/time stamp is gathered. Due to its format, a simple greater-than (GTR) comparison can be done do determine whether or not it is a later point of time than a cached one; if the criterion is fulfilled, the cache is updated accordingly.
The upper-case REM and ECHO commands constitute placeholders only for the real action to be performed on the files. Extend the script there as you like. Variable !LASTFILE! holds the full path to each encountered file.
So here is the code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "LOCATION=C:\SVN\nlbavwdocsvn\rep_doc_erpln\trunk\ERPLN"
set "FILELIST=.\filenames.txt"
set "WMICPROP=LastModified" & rem // {CreationDate | LastAccessed | LastModified}
pushd "%LOCATION%" || exit /B 1
for /F "usebackq eol=| delims=" %%L in ("%FILELIST%") do (
set "LASTFILE="
set "LASTFAGE=00000000000000.000000+000"
for /F "eol=| delims=" %%F in ('dir /B /S /A:-D "%%~L"') do (
set "FILE=%%F"
setlocal EnableDelayedExpansion
set "FILE=!FILE:\=\\!"
for /F "tokens=2 delims==" %%J in ('
2^> nul wmic DataFile WHERE ^(Name^="!FILE!"^) GET %WMICPROP% /VALUE ^|^| ^
2^> nul wmic DataFile WHERE Name^="!FILE!" GET %WMICPROP% /VALUE
') do for /F %%I in ("%%J") do (
endlocal
set "FAGE=%%I"
setlocal EnableDelayedExpansion
if !FAGE! GTR !LASTFAGE! (
endlocal
set "LASTFILE=%%F"
set "LASTFAGE=%%I"
setlocal EnableDelayedExpansion
)
)
endlocal
)
if defined LASTFILE (
setlocal EnableDelayedExpansion
REM Do whatever you want with the file here...
ECHO Newest file: "!LASTFILE!"
endlocal
)
)
popd
endlocal
exit /B
I need to delete duplicate folder names from a folder list. The duplicates occur when there's more than 1 subfolder. I end up with a list like below. I want to get rid of any line that has a sub2 folder.
folder1\sub1
folder2\sub1
folder2\sub1\sub2
folder3\sub1
Following code works if there is only one sub2 foldername, but it's awkward--hopeless if more than one sub2. There's gotta be a better way. Any help much appreciated.
#Echo off
SETLOCAL EnableDelayedExpansion
:: Write the sub2 foldernames to a tmp file
For /f "tokens=3 delims=\" %%I IN (folderlist.txt) DO Echo %%I >>temp.tmp
:: Set var for each sub2 name in tmp file and
:: call routine to write lines that don't contain that name
For /f %%G in (temp.tmp) do (
Set findstring=%%G
CALL :FindDup
)
EXIT
:findDup
For /f %%H in ('Type folderlist.txt ^|Find "!findstring!" /v') Do (
Echo %%H >> NoDup.txt
)
exit /b
FWIW: I'm using this command to generate the list, then deleting the path preceding folder1, folder2, etc
For /d %%G in (*) do dir /ad /on /s /b "%%G" >> folderlist.txt
you are almost there, if you just want the resulting list after eliminating the subfolders, just try to echo the appropiate lines to the list file, having copied it first into a temporary.
move folderlist.txt %temp%\folders.txt
for /f "tokens=1,2,* delims=\" %%a in (%temp%\folders.txt) do (
if .%%c==. echo %%a\%%b >>folderlist.txt
)
if you want to remove the folder from the disk, then change the line to
if not .%%c==. rd /s %%a\%%b\%%c
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%a IN (q20840158.txt) DO (
FOR /f "tokens=1,3delims=\" %%b IN ("%%a") DO IF "%%c"=="" ECHO(%%a
)
GOTO :EOF
I used a file named q20840158.txt containing your data for my testing.
But - It's really unclear what you mean by a "duplicate". How precisely do you define a duplicate in this context?
#ECHO OFF
SETLOCAL
COPY NUL newfile.txt >NUL 2>nul
FOR /f "delims=" %%a IN (q20840158.txt) DO (
ECHO %%a|FINDSTR /I /L /g:"newfile.txt" >NUL 2>NUL
IF ERRORLEVEL 1 >>"newfile.txt" ECHO(%%a
)
TYPE newfile.txt
GOTO :EOF
I used a file named q20840158.txt containing your data for my testing.
Produces newfile.txt
Ah- you want to make sure that any additions to the list don't contain a previous entry...
Firstly, there are a couple of similar questions on here to this (Rename file based on file Content batch file being the one I have tried to work an answer from - but I have no real clue what I'm doing), however I cannot find anything that meets my exact needs, and this is my first real foray into batch programming so the syntax is fairly new to me.
The question:
I have several hundred text files, with different names, where the header is formatted like so:
"Event Type : Full Histogram"
"Serial Number : xxxxxx"
"Version : V 10.60-8.17 "
"File Name : W133FA0Z.580H"
"Histogram Start Time : 12:39:08"
"Histogram Start Date : 2014-04-11"
I would like if possible to create a batch file to rename all the files in the folder to the format of:
StartDate StartTime
so for this example:
2014-04-11 12:39:08
My problems lie in the fact I'm not sure how to actually point it to where to find the string if it was for just one line (I've tried editing the answers in the question I posted above). And, futhermore, I have no idea how to add a second bit of code to find the StartTime string and then append that to the StartDate.
Thanks in advance,
Chris
Here is a very efficient method.
#echo off
pushd "pathToYourFolderContainingFilesToRename"
for /f "tokens=1,3 delims=:" %%A in (
'findstr /bc:^"\"Histogram Start Date :" *.txt'
) do for /f delims^=^"^ %%C in (
"%%B"
) do for /f tokens^=4-6^ delims^=^":^ %%D in (
'findstr /bc:^"\"Histogram Start Time :" "%%A"'
) do ren "%%A" "%%C %%D.%%E.%%F.txt"
popd
The 1st loop serves two purposes. It establishes file names that contain the start date string, as well as also returning the date string for each file.
The 2nd loop strips out spaces and quotes from the date string.
The 3rd loop parses out the start time from the file.
The 2nd and 3rd loops have very awkward syntax to enable including a quote in the list of delimiters. The 2nd loop sets DELIMS to a quote and a space. The 3rd set DELIMS to quote, colon, and a space.
Assuming you JUST have file formatted like in your description in the working directory :
#echo off&cls
setlocal EnableDelayedExpansion
for %%x in (*.txt) do (
set /a $sw=1
for /f "skip=4 tokens=2-4 delims=:" %%a in ('type "%%x"') do (
if !$sw! equ 1 set $Time=%%a-%%b-%%c
if !$sw! equ 2 (
set $Date=%%a
call:DoRen !$Time:~1,-1! !$Date:~1,-1! %%~nx%%~xx)
set /a $sw+=1
)
)
exit/b
:DoRen
echo ren "%3" "%2 %1"
If the output is OK you can remove the echo
The following will get the output you want, where the output will look like 2014-04-11 123908.
#echo off
set file=test.txt
for /f "delims=: tokens=2-4" %%a in ('find "Time" %file%') do set ftime=%%a%%b%%c
for /f "delims=: tokens=2" %%a in ('find "Date" %file%') do set fdate=%%a
echo %fdate:~1,-1% %ftime:~1,-1%
If all the files are in the same directory, then you can simply do this in a another for loop.
#echo off
setLocal enableDelayedExpansion
for /f %%f in ('dir C:\whatever\path\*.txt /B') do (
for /f "delims=: tokens=2-4" %%a in ('find "Time" %%a') do set ftime=%%a%%b%%c
for /f "delims=: tokens=2" %%a in ('find "Date" %%a') do set fdate=%%a
ren "%%~a" "!fdate:~1,-1! !ftime:~1,-1!.txt"
)
This will rename all text files in a specified directory the date and time in their contents. Note that this does not account for text files that do not have the date and time in their contents. You can (and probably should) add that as you see fit.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
DEL incorrectformat.log 2>nul
DEL alreadyprocessed.log 2>nul
SET "sourcedir=U:\sourcedir"
FOR /f "delims=" %%a IN ('dir /b /a-d "%sourcedir%\*.txt" ') DO (
SET keepprocessing=Y
SET "newname="
FOR /f "tokens=1-5delims=:" %%b IN (
'TYPE "%sourcedir%\%%a"^|findstr /n /r "$" ') DO IF DEFINED keepprocessing (
IF %%b==1 IF NOT "%%~c"=="Event Type " SET "keepprocessing="&>>incorrectformat.log ECHO %%a
IF %%b==5 SET newname=%%d%%e%%f
IF %%b==6 (
SET "keepprocessing="
SET "newname=%%d!newname!.txt"
SET "newname=!newname:"=!"
SET "newname=!newname:~1!"
IF "!newname!"=="%%a" (>>alreadyprocessed.log ECHO(%%a) ELSE (ECHO REN "%sourcedir%\%%a" "!newname!")
)
)
)
GOTO :EOF
Here's my version.
You'd need to set the value of sourcedir to your target directory.
A list of files not matching the specified format is produced as incorrectformat.log
A list of already-processed files is produced as alreadyprocessed.log
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.