I would like to rename a file as its parent folder example:
D:\Books\PDF\medical\001\99.jpg
D:\Books\PDF\medical\002\gg.jpg
to be:
D:\Books\PDF\medical\001\001.jpg
D:\Books\PDF\medical\002\002.jpg
I know this question asked before but I could not understand it.
also if it is possible I would like to put it in D:\Books\PDF\medical\
How to do it:
This is pretty easy:
1) Create a new text file named "myrename.bat" in "D:\Books\PDF\medical\".
2) Paste the following into it:
#echo off
pushd %~p1
for %%d in ("%CD%") do set "parentdir=%%~nd"
popd
move /Y %1 D:\Books\PDF\medical\"%parentdir%%~x1" > nul
3) From "D:\Books\PDF\medical\", run the batch file with its first argument being the name
of the file to be renamed. For instance, here's what you would do for the file "gg.jpg" in your example:
myrename 002\gg.jpg
This will rename the file "99.jpg" to "002.jpg" and move it to "D:\Books\PDF\medical\".
How it works
In batch, %~p1 returns the relative path of the first argument, i.e. it strips the folder. For instance, if you run myrename Bla\002\gg.jpg, %~p1 would be Bla\002. pushd then steps into this directory.
The for loop is supposed to extract the last folder from the current path, given by %CD%, and the value of %CD% is assigned to %%d. The expression %~nd is used to discard everything but the name of the last folder, the obtained result being stored in the variable parentdir. popd then returns to the original directory.
The move command both renames the file and moves it. The new filename is the value of parentdir and the extension %~x1, which is the extension of the original input file.
Hope this helps.
Related
I'm trying to copy specific files (search is always based on filenames) from 2 sub-directories (archive and archivestore) located in 1 directory (source) and copy them to another directory (SaveHere) by keeping the filename and extension but removing timestamp.
Tried the below script but it didn't work:
copy U:\clients\source\archive\ + U:\clients\source\archivestore\SampleFileName.file__01-02-2019_22-35-11-444_A X:\SaveHere\*.file
copy U:\clients\source\archive\ + U:\clients\source\archivestore\SampleFileName2.file_19-04-2019_20-35-56-676_A X:\SaveHere\*.file
pause
I expect that scripts checks both sub-directories (archive and archivestore) for the specified file names (SampleFileName.file_01-02-2019_22-35-11-444_A and SampleFileName2.file_19-04-2019_20-35-56-676_A) and wherever the files are found, to be copied to the targeted directory (X:\SaveHere\) with date-stamps (_01-02-2019_22-35-11-444_A and _19-04-2019_20-35-56-676_A) removed and only filename with extension remains (SampleFileName.file and SampleFileName2.file)
The question is not very clear. So I start with an example:
The directory U:\clients\source contains the directories and files:
archive
SampleFileName.file__01-02-2019_22-35-11-444_A
SampleFileName2.file_19-04-2019_20-35-56-676_A
archivestore
SampleFileName2.file_19-04-2019_20-35-56-676_A
The directory X:\SaveHere should contain after batch file execution:
SampleFileName.file
SampleFileName2.file ... preferred from directory archive.
One of lots of possible solutions for this file copying task is using loops:
#echo off
for %%I in ("SampleFileName.file" "SampleFileName2.file") do (
for %%J in ("U:\clients\source\archivestore" "U:\clients\source\archive") do (
for %%K in ("%%~J\%%~I_*") do copy /Y "%%K" "X:\SaveHere\%%~I" >nul
)
)
The most outer FOR runs two times the second FOR with first "SampleFileName.file" and second "SampleFileName2.file" assigned to loop variable I.
The second FOR runs two times the third FOR with first "U:\clients\source\archivestore" and second "U:\clients\source\archive" assigned to loop variable J.
So the third FOR is executed in total four times with the wildcard patterns:
"U:\clients\source\archivestore\SampleFileName.file_*"
"U:\clients\source\archive\SampleFileName.file_*"
"U:\clients\source\archivestore\SampleFileName2.file_*"
"U:\clients\source\archive\SampleFileName2.file_*"
The third FOR searches for non-hidden files matching the current wildcard pattern and runs command COPY for each file found.
Command COPY copies the file found by third FOR to directory X:\SaveHere with destination file name as defined by first FOR assigned currently to its loop variable I with overwriting a perhaps already existing file with same name in X:\SaveHere.
One more solution is using just two FOR:
#echo off
for /R "U:\clients\source\" %%I in ("SampleFileName*.file_*") do (
for /F "eol=| delims=_" %%J in ("%%~nxI") do copy /Y "%%I" "X:\SaveHere\%%J" >nul
)
The first FOR searches recursive in directory U:\clients\source and all its subdirectories for files matching the pattern SampleFileName*.file_* and assigns the found file name with full path to loop variable I before executing the second FOR.
The second FOR processes as string just the file name with file extension without path. It splits up to file name string into substrings using underscore as string delimiter. Just the first string underscore delimited string is assigned to loop variable J which is for the example once SampleFileName.file and twice SampleFileName2.file. Then second FOR runs the command COPY to copy the file with automatically truncated destination file name based on first underscore in source file name.
This solution does not work if there is an underscore left to date/time part in file name.
This solution has the disadvantage that the order of files found more than once in directory tree of U:\clients\source is not determined by the batch file code, but by the file system which returns the file names matching the pattern of first FOR loop.
Read the Microsoft article about Using Command Redirection Operators for an explanation of >nul.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
copy /?
echo /?
for /?
So I need CMD if statement script to move files to certain folders depending on image name. In other words, script needs to check image file name: 123456_large.jpg and move it to folder LARGE. But once file is moved to this folder it needs to be renamed to: 123456.jpg instead of 123456_large.jpg...
So if statement finds *_LARGE.jpg, move to LARGE folder and rename filename to delete _LARGE.
Anyone any ideas?
Assuming all the files are in one common folder and the large directory also exists in that common folder you could use this.
#echo off
FOR /F "tokens=1* delims=_" %%G IN ('dir /a-d /b *.jpg') DO (
IF /I "%%~nH"=="large" move "%%~G_%%~H" "large\%%~G%%~xH"
)
So essentially what this code does:
Gets a listing of all jpg files in the current folder the batch file is in.
Splits the file name at the first underscore and assigns the first part of the file name to the variable %%G and the rest of the file name to %%H.
Using the FOR variable modifiers, it then checks if the second part of the filename without the extension is equal to large. If it is, it then moves the file and renames it at the same time, again using the FOR variable modifiers.
If you want to read about the FOR modifiers open up a cmd prompt and type: FOR /?
It is the very last section of the help file.
This worked absolutely perfect! Now a few improvements... Is there a way to do the same thing a previous script, but if file is named: 123456_ALT1_large.jpg (or ALT2, ALT3, ALT4)?
I'm having trouble trying to copy and rename a file using only dos commands. I have a file of the format myfile20130218 and want to copy and rename it to some_other_file_20130218.
I know I can use copy source dest but I'm having trouble with how to isolate the date and preserve it. I cannot guarantee that he date will be today's date so that is ruled out, the source file will always be the same name.
I can run either a series of commands or a batch script, but thing that that I am currently having trouble with, is after I find a match that I need to copy, using myfile????????, how can I now get those file names to pull the dates off them?
EDIT: for clarification I will be looking at files in a known directory, as above, I will know the format of the file name, and will only be checking a specific directory for it. The process that checks the directory is a ConnectDirect file watcher, so when a file is found matching myfile20130218 I can fire off some commands, but don't know how to check the directory and get the name of the file present.
Something like this should work:
%oldname:~-8% extracts the last 8 characters from %oldname% which are then appended to the new filename.
Update: If you can identify the file with an external program and then call the batch script with the file name
copyfile.cmd C:\path\to\myfile20130218
you could do something like this:
set oldname=%~nx1
set newname=%~dp1some_other_file_%oldname:~-8%
copy "%~f1" "%newname%"
Update 2: If you know folder and the format you could call the script with the folder
copyfile.cmd C:\folder
and do something like this:
#echo off
setlocal EnableDelayedExpansion
for /f %%f in (
'dir /b "%~f1" ^| findstr /r "myfile[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$"'
) do (
set oldname=%~f1\%%f
set newname=%~f1\my_other_name_!oldname:~-8!
copy "!oldname!" "!newname!"
)
endlocal
Edit: Script breakdown.
setlocal EnableDelayedExpansion enables variable expansion inside loops and conditionals.
for /f %%f in ('...') executes the command between the single quotes and then loops over the output of that command.
dir /b "%~f1" lists the content of the given directory (%~f1 expands to the full path of the first argument passed to the script) in simple mode (no header, no summary).
findstr /r "myfile[0-9]...[0-9]$" filters the input for strings that end with the substring "myfile" followed by 8 digits. The circumflex before the pipe (^|) escapes the pipe, because otherwise it would take precedence over the for command, which would effectively split the for command in half, resulting in an invalid command-line.
set oldname=%~f1\%%f assign the full path to a matching file to the variable oldname.
set newname=%~f1\my_other_name_!oldname:~-8! assign the full path to the new filename ("my_other_name_" followed by the trailing 8 digits from oldname) to the variable newname.
copy "!oldname!" "!newname!" I don't need to explain this, do I?
So my many attempts to search for a solution have resulted in a million ways to find the folder of the bat file being executed, however what I am looking to do is find the folder for the filename being passed to the bat file.
Example:
C:\Temp\runthis.bat "C:\Blah\Ah Argh\rage.txt"
I want to get a string within that bat file that is simply "C:\Blah\Ah Argh\", alternatively I would also be able to work with getting a string of "rage.txt"
Editing to explain why: Looking to check for the filename within another txt file which is the directory listing of a ftp server to verify that a file successfully uploaded to it. Then if successful I need to move the file to a subfolder of the original folder \uploaded\ but we have many of these folders setup so I can't hard code it.
Thanks
#echo off
The file path is %~dp1
The file name is %~nx1
The parameter modifiers are the same as for FOR variables.
Type 'HELP CALL' from a command prompt for a full list of parameter modifiers.
#echo off
if %1X==X echo Syntax: %0 "path"
rem The for loop doesn't actually loop. You can split strings with it, but in
rem this case we don't. So there is only one iteration in which %%X will
rem contain the full path.
rem Pass it %1, which is the first parameter. Note the quotes, which are
rem required if you don't add quotes around the parameter and optional (but
rem still valid) when you do.
for /F "delims=|" %%X in ("%1") do (
rem FOR LOOP variables can be used with certain modifiers, preceeded by a
rem tilde. In this case I'm using d and p, which stand for drive and path,
rem effectively trimming the file name from the path.
echo %%~dpX
rem The ~n modifier selects the file name only. ~x is for extension
echo %%~nxX
)
I am trying to write a batch file to copy a large number of files. I want to be able to take the file and move it to a specific folder based on its file name.
For example, I have a directory structure like this:
C:/
FolderA
File1.xyz
File2.xyz
FolderB
File3.xyz
I would like to have a batch file that looks for all *.xyz files and copies them each to a folder according to their filename. So the above files would end up in the following directories.
File1.xyz gets copied to D:/FolderA/File1/File1.xyz
File2.xyz gets copied to D:/FolderA/File2/File2.xyz
File3.xyz gets copied to D:/FolderB/File3/File3.xyz
I know this should be possible using a FOR loop in a batch file, but I do not know how to take the text replaced by the wild card and use it as a variable (so I can create a folder with the same name.)
for /R C:\ %%f in (*.xyz) do (
if not exist D:%%~Pf%%~Nf md D:%%~Pf%%~Nf
copy %%f D:%%~Pf%%~Nf/%%~NXf
)
The FOR variable modifiers give the info you need:
%%~D Expands to a Drive letter only.
%%~P Expands to a Path only, including an ending backslash.
%%~N Expands to the Name only.
%%~X Expands to the eXtension only.
Type FOR /? for further details.
Perhaps you need to copy the directory structure first with:
XCOPY C:\ D:\ /T