How can I remove a specific part of many folders names using .bat files? - windows

My university is using a proprietary system that outputs data in a very specific way in which each "module" is output into folders following the structure (4 digit numeral) - (name of module)
ex: 5574-CHEM104
I need to remove the name and hyphen so that only the numeral remains:
5574-CHEM104 > 5574
The problem is that there's thousands of these folders and there's no way I could do it by hand. I'm having difficulty trying to automate the process, so if anyone could at least point out a command I could look into it would help immensely
I've tried the REN command, putting "REN 5574-CHEM104 5574", but it only works for one folder. There's thousands of folders, each with different numerals, under "CHEM104", for example, and I need for the program to rename the folder no matter the original name into the first 4 original numerals, which I can't figure out. Thanks!

#ECHO OFF
SETLOCAL
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes 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"
FOR /f "delims=" %%e IN (
'dir /b /ad "%sourcedir%\*" '
) DO FOR /f "delims=-" %%o IN ("%%e") DO ECHO REN "%sourcedir%\%%e" "%%o"
)
GOTO :EOF
Always verify against a test directory before applying to real data.
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 directories.
Using a list of the directory-names, names only (/b) and directories only (/ad), tokenise the name using - as a delimiter and execute the rename using the token assigned to %%o (default is first token)

Related

Batch Create Several Folders Based on Multiple Filenames, and Move Multiple Related Files to The Created Folders

Every week, one of my co-workers has had to go through a folder with hundreds of demuxed video and audio files, rename each one individually for a specific city TV station and then sort them into folders based on the name of the city. I've created a .bat file to rename them all for him, and now I'd like to create a .bat file that creates new directories based on the filenames, and places the corresponding files into the new folders. I copied a few of the files to test with.
So the end result will be a "Houston" folder with all it's corresponding files, a "Compton" folder with it's files, a "Moline" folder, etc, etc... for every city, up to around 200 cities, and we're only getting more.
He's currently searching "Houston", cutting all the files that come up, creating a new folder manually, naming it "Houston" and pasting all the files into his new folder. FOR EVERY CITY. 200 TIMES. And it takes hours.
The files are ALWAYS named with this system: X### Random City, ST
With my little wee programming knowledge, I'm supposing that the script could detect all the characters after the first space, and before the comma, copy those characters (Random City), create a new folder, name it the copied characters (Random City) then move any files containing "Random City" in their filename into the newly created folder. The end result would be as such, just with a lot more folders.
Is there anyone more advanced than me who could explain the best way to to this?
I apologize in advance if I'm in the wrong place or not savvy enough. Cheers!
UPDATE: I messed around, learned about tokens and delimiters, variables etc. Here is what I have which works amazingly, except I'm not sure how to remove the comma at the end of the city name. I'm using space as the delimiter, which makes the text chunks the tokens if I understand correctly, including my comma, using tokens=2. Another problem that arises; Say there's a city with two text chunks (tokens) eg. San Fransisco, Baton Rouge. How could I grab both of them, using the comma as my stopping point? My code is below.
#echo off
setlocal enabledelayedexpansion
for %%A in (*.m2v *.mpa) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=2* delims= " %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! doesn't exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
UPDATE 2: I found a meh workaround to get rid of the comma, by adding it as a delimiter, but I'm still trying to wrap my head around the 2 word cities. My Baton Rouge and San Fransisco folders are being named respectively, "Baton" and "San". Here is my code so far, I'll update if I find a better way.
setlocal enabledelayedexpansion
for %%A in (*.m2v *.mpa) do (
echo file found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "delims=," %%B in ("%%A") do set fname=%%~nB
for /f "tokens=2* delims= " %%D in ("!fname!") do set folname=%%D
echo folder name !folname!
if not exist "!folname!" (
echo Folder !folname! doesn't exist, creating
md "!folname!"
) else (
echo Folder !folname! exists
)
echo Moving file %%A to folder !folname!
move "%%A" "!folname!"
)
echo Finished
pause
UPDATE 3
Here is my code which worked. However, if the number of characters in your filename prefixes/suffixes changes, it will screw things up and you'll have to edit code.
#ECHO OFF
SETLOCAL enabledelayedexpansion
FOR %%A in (*.m2v *.mpa) do (
ECHO file found %%A
FOR /F "delims=" %%B in ("%%A") do set fname=%%~nB
SET folname=!fname:~5,-4!
ECHO folder name !folname!
if not exist "!folname!" (
ECHO Folder !folname! doesn't exist, creating
MD "!folname!"
) else (
ECHO Folder !folname! exists
)
ECHO Moving file %%A to folder !folname!
MOVE "%%A" "!folname!"
)
ECHO Finished
PAUSE
Using the SET folname=!fname:~5,-4!allows me to trim the M373 prefix, 5 characters in, and the , TX suffix, 4 characters in, removing the comma and salvaging the city name, regardless of how long it is, or how many words it is (eg. West Palm Beach, FL) . Antares mentioned this solution in his answer which worked like a charm.
BUT IT ALSO MADE ME THINK
If the number of characters in the prefix changes, which is likely, I'll either have to edit the batch file every time, or create a specific batch file for each circumstance. Not terrible, but not great either. So I went with Michael Heath's answer which works flawlessly. I'm not smart enough yet to know exactly why, but I'm gonna dissect it and find out. I have a lot of learning to do. Thanks, everyone!
#echo off
setlocal
rem A=Fullpath, B=Name before comma, C=B prefix, D=B without prefix.
for /f "delims=" %%A in ('dir /b *.m2v *.mpa') do (
for /f "delims=," %%B in ("%%~nA") do (
for /f "tokens=1,*" %%C in ("%%~B") do (
if not exist "%%~D\" (
echo Folder "%%~D" doesn't exist, creating
md "%%~D"
)
if exist "%%~D\" (
echo Moving file "%%~A" to folder "%%~D\"
move /y "%%~A" "%%~D\"
) else echo Folder "%%~D\" doesn't exist
)
)
)
echo Finished
pause
3 for loops to get the tokens needed.
1st will get the fullpath.
2nd to get the name before the comma.
3rd to get the name without the prefix.
In the nested for loops check if folder exists, create it if not. Then if folder exists, move file inside.
Here is my code which worked. However, if the number of characters in your filename prefixes/suffixes changes, it will screw things up and you'll have to edit code.
#ECHO OFF
SETLOCAL enabledelayedexpansion
FOR %%A in (*.m2v *.mpa) do (
ECHO file found %%A
FOR /F "delims=" %%B in ("%%A") do set fname=%%~nB
SET folname=!fname:~5,-4!
ECHO folder name !folname!
if not exist "!folname!" (
ECHO Folder !folname! doesn't exist, creating
MD "!folname!"
) else (
ECHO Folder !folname! exists
)
ECHO Moving file %%A to folder !folname!
MOVE "%%A" "!folname!"
)
ECHO Finished
PAUSE
Using the SET folname=!fname:~5,-4!allows me to trim the M373 prefix, 5 characters in, and the , TX suffix, 4 characters in, removing the comma and salvaging the city name, regardless of how long it is, or how many words it is (eg. West Palm Beach, FL) . Antares mentioned this solution in his answer which worked like a charm.
BUT IT ALSO MADE ME THINK
If the number of characters in the prefix changes, which is likely, I'll either have to edit the batch file every time, or create a specific batch file for each circumstance. Not terrible, but not great either. So I went with Michael Heath's answer which works flawlessly. I'm not smart enough yet to know exactly why, but I'm gonna dissect it and find out. I have a lot of learning to do. Thanks, everyone!
Before Image
After Image
I can give you some hints. If you have a more specific problem case, feel free to update your question again.
You can cut the last X characters of a String like this: %variablename:~0,-X%
If you know the variables with the city parts, e.g. %%D and %%E or something, you can concatenate them again like this md "%%D %%E". However, this works just for a fixed number of tokens, like the two here.
You can store this concatenations in an own variable, if you need the result outside of your for-loop. Use set myVariable=%%D %%E for example, and show it with %myVariable% or !myVariable! (when delayed expansion is needed), for example md "%myVariable%".
A nifty workaround: if there are only a small number of "special cities" to take into consideration, then you could just add some rename commands at the end of your script, like rename San "San Francisco", rename Baton "Baton Rouge", etc. Will not work well, if there are more "San" cities (e.g. "San Bernadino"), because this cannot be distinguished anymore. But in this case, the copying into separate folders would already fail as well.
In your script you make a check for an existing folder. I think you can omit that. md or mkdir either create that directory or do nothing if it exists. Well, they do print a message to the console, which can be ignored. If you do not want to see them, redirect the error message stream to nul like this md myFolder 2>nul. This will swallow any error messages, but it is unlikely that you get any other error message than that in your scenario.
You could simplify your approach like this: I reckon your file renaming works well. Your "copy" script could be just a list of commands which are stated explicitly (and also could be edited fairly quickly if new cities are to be considered).
Set the batch file up like this with entries for each city:
#echo off
mkdir "Moline"
copy "*Moline*.*" "Moline"
mkdir "San Francisco"
copy "*San Francisco*.*" "San Francisco"
...
echo done.
Side effect is, that the folders for each city will be created, not just those where files are copied into. May be it suits your needs anyhow.
Also, I would like to give you pointers to sources of help/documentation:
On the command line you can get extensive help by executing the commands used in your batch file and appending /?. For example set /? gives you a lot of useful things you can do with variables/String manipulations.
Try: for /?, if /? (regarding errorlevel for example), maybe call /?, goto /?, and others.
A very good source for all the command line commands is https://www.ss64.com. This site provides extensive help even for PowerShell and Linux Bash and others. Relevant to you in this case would be CMD, direct link: https://ss64.com/nt/
Edit/Update:
Check out symbol replacement on the set command to build something like
if "%myVariable:~0,1%" == "M" (set myvariable=%myvariable:~1%)
The first part "cuts" the first character and checks, if it is an M and if so, it keeps everything except the first character. With this you could make your filenames even out to process them inside your batch file.
You can also "remove" a letter or substring with %myVariable:, TX=% which would replace any ", TX" occurance with "nothing" for example.
Oh, this could also help to remove any spaces in the filename. Then you could extract the "SanFrancisco" without a spaces problem ;) The folder name would be without space though. This could be resolved with further rename commands at the end.
Here's an alternative method, just for the sake of variety:
#Echo Off
SetLocal DisableDelayedExpansion
Set "SourceDir=.\Batch Rename\BACKUP"
If Exist "%SourceDir%\" For /F "EOL=|Delims=" %%G In (
'%__AppDir__%where.exe "%SourceDir%":"*, ??.m??" 2^>NUL'
)Do (Set "FileBaseName=%%~nG"&SetLocal EnableDelayedExpansion
For /F "EOL=|Delims=," %%H In ("!FileBaseName:* =!")Do (EndLocal
%__AppDir__%Robocopy.exe "%%~dpG." "%%~dpG%%H" "%%~nxG" /Mov>NUL))
This method filters your files with the where command. It selects for moving, only file names which end with a comma, followed by a space, followed by two letters, followed by a three letter extension beginning with the character m. It moves the files, automatically creating the destination directories if they do not exist, using the robocopy command. It uses only two for loops, the second of which, isolates the string between the first space and the next comma.
I have made it so that the script can be located anywhere, not necessarily in the directory with the files. This location is set on line 3 of the script, If you wish to modify it, please ensure that your location remains between the = and the closing double-quote, ", and does not end with a trailing back-slash, \. It is currently set to a relative directory, (based upon that visible in your screen-shot), but you could obviously use an absolute path too, e.g. Set "SourceDir=C:\Users\UserName\Videos". If you wish to keep the script in the same directory as the files to be moved, change it to read Set "SourceDir=." and just double-click it to run.
When I had to develop a script for the task at hand I would probably implement a few safety features in order to not move wrong files. Your sample data show pairs of .m2v and .mpa files, but I would likely not consider that as granted. Also would I not rely on a fixed-length prefix. Finally, I would perhaps also account for lit's comment.
So here is my attempt (see all the explanatory rem-remarks in the code):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=%~dp0." & rem // (root directory containing the files to be processed)
set "_MASK=M??? *, ??.m2v" & rem // (mask to find the files to be processed)
set _EXTS=".m2v" ".mpa" & rem /* (list of extensions that must all be present;
rem extensions are not checked if this is empty;
rem `_MASK` should then be changed to end with `.m*`) */
set "_FILT=^M[0-9][0-9][0-9] [^,][^,]*, [A-Z][A-Z]\.[^\.][^\.]*$"
rem // (additional filter to find files; deactivate by `.*`)
set "_SEPS=," & rem /* (defines (a) separator character(s) to derive the
rem sub-directory; leave it blank to use full name) */
rem // Change into the root directory:
pushd "%_ROOT%" && (
rem /* Loop through all files matching the mask as well as the additional filter;
rem if the post-filtering is not needed, remove `^|` and everything behind: */
for /F "delims= eol=|" %%F in ('
dir /B /A:-D-H-S "%_MASK%" ^| findstr /I /R /C:"%_FILT%"
') do (
rem // Get the portion in front of the `,` of the file name:
for /F "delims=%_SEPS% eol=|" %%G in ("%%~nF") do (
rem // Split that portion at the first space to get the city name:
for /F "tokens=1* eol=|" %%H in ("%%G") do (
rem // initialise flag that indicates whether to move the current file:
set "FLAG=#"
rem // Skip the following checks if there are no extensions defined:
if defined _EXTS (
rem // Loop through the extensions in the list:
for %%E in (%_EXTS%) do (
rem /* Reset flag if file with current name and iterated extension
rem cannot be found; this ensures that files with all listed
rem extensions do exist, otherwise no files are moved: */
if not exist "%%~nF%%~E" set "FLAG="
rem /* Reset flag if file with current name and iterated extension
rem is actually a directory (though this is very unlikely): */
rem if exist "%%~nF%%~E\*" set "FLAG="
rem /* Reset flag if file with current name and iterated extension
rem is already located in the target sub-directory: */
if exist "%%I\%%~nF%%~E" set "FLAG="
)
)
rem // Do the following steps only if the flag has not been reset:
if defined FLAG (
rem // Create target sub-directory (suppress potential error message):
2> nul md "%%I"
rem // Check if there are dedicated extensions defined:
if defined _EXTS (
rem // Loop through the extensions in the list again:
for %%E in (%_EXTS%) do (
rem /* Move file with current name and iterated extension;
rem nothing is overwritten due to the preceding checks: */
> nul move "%%~nF%%~E" "%%I\%%~nF%%~E"
)
) else (
rem /* Empty list of extensions, hence just move the current file;
rem if you do want to overwrite, remove the `if exist´ part: */
if not exist "%%I\%%F" > nul move /Y "%%F" "%%I\%%F"
)
)
)
)
)
rem // Return from root directory:
popd
)
endlocal
exit /B
The values in the Define constants here: section at the top of the script are defined to suit your sample data, but they can easily be adapted there to configure the script at one place:
_ROOT: points to the directory where your input files are; %~dp0. points to the parent directory of the script, but you may of course specify any other absolute directory path here;
_MASK: is a file pattern that matches one file per pair (only .m2v files, others are covered by _EXTS); M??? matches the four-character prefix, but you can change it to M?*, for instance, to also match prefixes like M1 or M9999; if you do so, however, also edit _FILT accordingly;
_EXTS: defines a list of extensions that all must be present; that means for a certain base file name (like M372 Houston, TX, there must exist a file per each given extension, hence M372 Houston, TX.m2v and M372 Houston, TX.mpa in our situation, otherwise these files are not going to be moved; if you do not care if such a pair is complete or not, simply state set "_EXTS=" (so clear it) and change the extension of _MASK from .m2v to .m*, so all files with an extension beginning with .m are moved;
_FILT: constitutes an additional filter for file names in order to exclude wrong files; this currently also reflects a four-character prefix, but if this is not always the case, just change M[0-9][0-9][0-9] to M[0-9]*; if you do not want to filter, set this to .*, so it matches everything;
_SEPS: defines the character(s) to split the base file name in order to derive the respective sub-directory, so everything ending before that character and beginning after the first SPACE is the resulting sub-directory name; if you do not define a character here, the whole remaining base file name (so everything after the first SPACE until but not including the (last) .) is taken;

Parsing every file in submap recursively to output folder whilst maintaining relativity

I'm using the following batch code to convert all files in a certain directory if the target file doesn't already exist however I'm stuck at getting this to run through every submap and file within that (and keep the output relative with that submap)
So I currently use this:
for %%f in (input/textures/*.*) do ( IF NOT EXIST "ouput/textures/%%~nf.dds" (
"bin/ThempImageParser.exe" "input/textures/%%f" "ouput/textures/%%~nf.dds"
)
)
This works perfectly for a single folder (as was intended), it takes all the files in that specific folder, and passes them as arguments to my executable, which then outputs the file on the path of the second argument.
However this also contains a flaw (this is an additional problem though..) as it does not work if the output -folder- does not exist, so if possible I'd also want it to create the folder if need be.
I've found some batch documentation (I really don't have much experience with Batch) showing me a command called FORFILES and the /R parameter, however I couldn't adjust this so it'd keep the relative paths for the output too, it'd require string manipulation and I have no clue on how to do that.
So the result I'm after is something like this, it takes any file deeper than "input/textures/ for example:
input/textures/some/very/deep/submap/why/does/it/go/on/myfile.anyExtension
it should then take that file (and relative path) and basically change "input" with "output" and replace the file extension with .dds like this:
ouput/textures/some/very/deep/submap/why/does/it/go/on/myfile.dds
and pass those two strings to my executable.
#ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir\wherever\something"
FOR /f "delims=" %%a IN ('xcopy /y /L /s "%sourcedir%\*"') DO (
SET "destfile=%%a"
SET "destfile=!destfile:*%sourcedir%=%destdir%!"
IF /i "%%a" neq "!destfile!" (
FOR %%m IN ("!destfile!") DO IF NOT EXIST "%%~dpm%%~na.dds" (
ECHO MD "%%~dpm"
ECHO "bin\ThempImageParser.exe" "%%a" "%%~dpm%%~na.dds"
)
)
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
First, perform an xcopy with the /L option to list-only the individual fullnames of files that would be copied by the xcopy.
Assign each name found from %%a to destfile, then remove all characters before the source-directoryname from that filename, and replace that string with the destination directoryname.
This will yield the destination name for the file (with the original extension). The only exception will be the very last output line, which is a count-of-files report. Since this line will not contain the source directoryname, the replacement will not take place, so %%a will be the same as !destfile! - so we eliminate that.
Now assign the destination filename to a metavariable so we can select its various parts, and if the filename made from the destination drive and pathname, the name part of the original file and .dds does not exist, then make the destination directoryname and execute the imageparser, providing the desired output filename.
Note that these last two are ECHOed instead of being executed for testing purposes. Remove the ECHOes to actually perform the command.
Note that / is a switch-indicator, \ is a directory-separator.
Note that MD will report an error if the directory already exists. Append 2>nul to the end of the md command to suppress that error message.

Need to view merged photos directory in date sequence

I have two photo folders taken with different cameras, and want to merge them by date, and then view the combined directory in date sequence. I have merged them, and the directory dates look good, but the tools I use insist of showing the photos in name sequence, which is not what I want. I thought of doing a batch rename function to make the date part of the file names, using a bat file, but the DOS DIR command doesn't seem to use this date - if I do
for /f "skip=5 tokens=1,2,4,5* delims= " %%i in ('dir /a:-d /o:d /t:c') do (
etc., most of the file dates are correct, but some of the files seem to be using the "created date" of the directory.
Maybe there is a simple solution as this must be a common problem, but I haven't found a good solution - short of doing a laborious manual rename of some 700+ files!
Help would be appreciated!
Paul M.
for /f "tokens=1*delims=[]" %%a in ('dir /b /a-d /od /t:c^|find /v /n "" ') do echo ren "%%b" "%%a%%~xb"
Perform a directory scan of the source directory, in /b basic mode /a-d without directories in date order selecting created-date, number in brackets each line that doesn't match an empty string and assign each filename found to %%b and the number to %%a
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.
Note: filenames that begin [ or ] will be processed incorrectly. If an existing file has a name which belongs to the target nameset (ie 1.? 2.? etc.) then simply prefix the target name with a prefix that doesn't already exist, eg ren "%%b" "new_%%a%%~xb" (where there are no existing files named new_*)
I'm not sure about Win7's capability when displaying files using the utility you are using (Explorer?) Win10 has the capability of selecting display by creation-date (select sort by then creation-date)
If you are sure you are sorting by creation-date then probably you'd need to select some other sorting scheme (change t:c to t perhaps)
If there are filenames that aren't being converted, then you are probably adding files (called img*) to a directory that already contains files named 1,2,3... - in fact, it's difficult to see how that phenomenon could happen otherwise.
Change "%%a%%~xb" in the rename command to "xyz%%a%%~xb" and you should find that the files are then all renamed xyz1,xyz2,xyz3 etc. If you then reprocess the files with xyz removed, the names should become 1,2,3 with no omissions.

Renaming a batch file and keeping part of the filename

I've seen plenty of posts on similar requests but I can't quite find one that suits what I am trying to do. It is fairly simple but I cannot seem to get it.
ren FILE??.txt FILE%Year%%Month%%Day%??.txt
copy FILE%Year%%Month%%Day%??.txt C:\Users\me\Desktop\Batch\renamed\achod%Year%%Month%%Day%??.txt
I cannot get the script to keep the '??' which represents random characters the first file may have.
Any help is appreciated.
You won't be able to rename files directly using a wildcard character. Instead you need to locate all the applicable files and then rename each.
The script below works under the assumptions of your question/comments:
File name is 6 chars long.
Only the last 2 chars are interchangeable.
Of course, the script could be very easily adapted to accomodate other settings but this does just as you requested.
SETLOCAL EnableDelayedExpansion
REM Set your Year, Month, Day variable values here.
REM They will be used for file renaming.
...
CD "C:\Path\To\Files"
FOR /F "usebackq tokens=* delims=" %%A IN (`DIR "File??.txt" /B /A:-D`) DO (
REM Extract the last 2 chars of the file name.
SET FileName=%%~nA
SET First4=!FileName:~0,4!
SET Last2=!FileName:~-2!
REM Rename the file, inserting the new data.
RENAME "%%A" "!First4!%Year%%Month%%Day%!Last2!%%~xA"
)
ENDLOCAL

For loop in batch file reading a file of File Paths

I want to write a Windows batch file script that will loop through a text file of FILE PATHS, do some work using data from each file path, then ultimately delete the file.
I started by running the FORFILES command and sending its output (the #PATH parameter is the full path of any file it matches) to a text file (results.txt).
I end up with a results.txt file like this:
"C:/Windows/Dir1/fileA.log"
"C:/Windows/Dir1/fileA.log"
"C:/Windows/Dir2/fileC.log"
"C:/Windows/Dir3/fileB.log"
What I want to do is:
Use a FOR loop and read each line in the results.txt file
For each line (file path), strip out the directory name that the log file is sitting in (ie: Dir1, Dir2, etc..) and create a directory with that SAME name in a different location (ie. D:/Archive/Backups/Dir1, D:/Archive/Backups/Dir2, etc..) -- assuming the directory doesn't exist.
Move the actual .log file to a zip file in that directory [I have code to do this].
Delete the .log file from its original location. [Pretty straightforward]
I'm having trouble figuring out the best way to accomplish the first 2 steps. My FOR loop seems to stop after reading the very first line:
FOR /F "tokens=1,2,3,4,5,6,7,8,9,10 delims=\" %%G in ("results.txt") DO (
...
)
You don't want to parse the path with the tokens/delims options because you don't know how many directory levels you are dealing with. You want to preserve each line in its entirety. TO parse the path you want to use the FOR variable modifiers. (type HELP FOR from the command line and look at the last section of the output)
%%~pG gives the path (without the drive or file name). If we then strip off the last \, we can go through another FOR iteration and get the name (and possible extension) of the file's directory by using %%~nxA.
The toggling of delayed expansion is just to protect against a possible ! in the path. If you know that no path contains ! then you can simply enable delayed expansion at the top of the script and be done with it.
EDIT - this code has been modified significantly since Aacini pointed out that I misread the requirements. It should satisfy the requirements now.
for /f "usebackq delims=" %%G in ("results.txt") do (
set "myPath=%~pG"
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%A in ("!myPath:~0,-1!") do (
endlocal
if not exist d:\Archive\Backups\%%~nxA md d:\Archive\Backups\%%~nxA
rem ::zip %%G into zip file in the D: location
rem ::you should be able to create the zip with the move option
rem ::so you don't have to del the file
)
)
I wrote this to timestamp files before offloading to SFTP.
Hope you find it useful.
The timestamp coding may seem irrelevant to your issue, but I left it because it's a good example of dissecting the filename itself.
I suggest you put an ECHO in front of the REN command for testing. Different shells may have different results.
In the end, the delayedexpansion command wasn't necessary. It was the sub-routine that fixed my issues with variables inside the loop. That could possibly be because of my OS ver. (Win 8.1) - It wouldn't hurt to leave it.
#echo off
cls
setlocal enabledelayedexpansion
if %time:~0,2% geq 10 set TIMESTAMP=%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%
if %time:~0,2% leq 9 set TIMESTAMP=%date:~10,4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2%
echo TimeStamp=%TIMESTAMP%
echo.
for %%G in (*.txt) do (
set OLDNAME=%%G
call :MXYZPTLK
)
dir *.txt
goto :EOF
:MXYZPTLK
echo OldName=%OLDNAME%
ren %OLDNAME% %OLDNAME:~0,-4%_%TIMESTAMP%%OLDNAME:~-4,4%
echo.
:END
You have two minor problems:
The path separator in the file is '/' but you use '\' in the for loop.
The quotes around "results.txt" stop it working.
This works. Don't write quotes to results.txt and you won't get a quote at the end of the filename.
#echo off
FOR /F "tokens=3,4 delims=/" %%I in (results.txt) DO (
REM Directory
echo %%I
REM File
echo %%J
)

Resources