I have made a batch script to move and rename a file by dragging and dropping a file onto the script. This will assume the source of the file is unknown, but the target directory is.
My solution was to CD to the target directory, reverse the source file name, use the for command with backslash as a delim to have the file name, then reverse it again then finally rename it.
Just wondering if there was an easier solution.
#echo off
echo %1
set newSong=%1
cd "C:\Riot Games\League of Legends\RADS\projects\lol_air_client\releases\0.0.0.230\deploy\assets\sounds\ambient"
if not exist LoginScreenIntro.mp3.bak rename LoginScreenIntro.mp3 LoginScreenIntro.mp3.bak
del LoginScreenIntro.mp3
copy %newSong% "%CD%"
Call :ReverseString %newSong%
Set ReverseString.Result="%ReverseString.Result%"
for /f "tokens=1 delims=\" %%a in (%ReverseString.Result%) do set reversesong=%%a
Call :ReverseString "%reversesong%"
set newSong=%ReverseString.Result%
rename "%newSong%" LoginScreenIntro.mp3
pause
:ReverseString
Set ReverseString.TempVar=%~1
Set ReverseString.Result=
:ReverseString.Loop
Set ReverseString.Result=%ReverseString.TempVar:~0,1%%ReverseString.Result%
Set ReverseString.TempVar=%ReverseString.TempVar:~1,999%
if not "%ReverseString.TempVar%"=="" goto ReverseString.Loop
Goto :Eof
How about this?
ren %1 NewName.ext
move %~dp1\NewName.ext NewDir
Heh, all I needed was
set newsong=%~n1%~x1
Related
I am trying to rename every image in a directory to add the date that each file was created, however, I keep either getting "invalid syntax" or "A duplicate file name exists, or the file cannot be found"
I am running Windows 10, and accessing the images off a flash drive (hence the short file path). I tried having all the code in one for-loop, when that didn't work I tried using batch functions, no dice. I did see someone mention on another thread to use delayed expansion, I would be up for using this if someone could give a better explanation than the /? command.
#echo off
REM batch file is placed in top of F drive, same as "images 2017+"
cd "F:\images 2017+"
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~nF" "%%~tF"
goto :eof
:renER
cd "F:\images 2017+"
pause
echo %1
echo %2
rename %1.jpg %1_%2.jpg
pause
goto :eof
:end
For every .jpg file in "images 2017+", the date which that file was created would be stuck onto the end after a space.
thisIsMyFile.jpg made at 5-13-2017, would become thisIsMyFile 5-13-2017.jpg
Current output
EDIT:
I am CDing into the same directory as the images are, then using the passed variables to locate the correct image (The date is one of the passed variables, and shows up in the echo command).
I notice that you only want the date, not the time so you can do that as follows using your existing Call to a label, There is also no need to use FOR /R in this case so I'll use a normal for loop:
#echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
CALL :RenER "%%~fA" %%~tA
)
GOTO :eof
:RenER
PAUSE
ECHO %1
ECHO %2
SET "_tmp=%~2"
SET "_tmp=%tmp:/=-"
REN "%~1" "%~n1_%_tmp%%~x1"
PAUSE
GOTO :eof
Notice how above we are dropping the Time off immediately by not wrapping it in quotes since you don't want that to be part of the file name.
You can also forgo the call to a label entirely without needing delayed expansion by using a second loop, as a matter of preference I think this is quite a bit cleaner!
#echo off
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
FOR /F "Tokens=1-3 Delims=/ " %%a IN ('echo.%%~tA') DO (
PAUSE
ECHO.%%~fA
ECHO.%%~tA
REN "%%~fA" "%%~nA_%%a-%%b-%%c%%~xA"
PAUSE
)
)
this is nice and clean and with a minor edit we can paste it directly into the CMD Prompt which is nicer still This is because we are not using DelayedExpansion, Calling a Label, or using Temp variables so by changing the %%s to %s, we can then Paste this directly into the CMD Line which is often more convenient when doing these sorts of operations:
This Multi-line will do just fine to be pasted into CMD directly:
FOR %%A IN ("F:\images 2017+\*.jpg") DO (
FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO #(
PAUSE
ECHO.%~fA
ECHO.%~tA
REN "%~fA" "%~nA_%a-%b-%c%~xA"
PAUSE
)
)
or, as a single line to paste into CMD if you prefer:
FOR %A IN ("F:\images 2017+\*.jpg") DO #( FOR /F "Tokens=1-3 Delims=/ " %a IN ('echo.%~tA') DO #( PAUSE& ECHO.%~fA& ECHO.%~tA& REN "%~fA" "%~nA_%a-%b-%c%~xA"& PAUSE ) )
no need to cd anywhere. ren takes a full path/filename for source - just the destination must be a filename only. So ... do call :renER "%%~fF" "%%~tF" is fine (no need to snip the extension and add it again later). In the subroutine reformat the time to a valid string and reassemble the destination file name:
#echo off
FOR /R "F:\images 2017+" %%F in (*.jpg) do call :renER "%%~fF" "%%~tF"
goto :eof
:renER
pause
echo %1
echo %2
set "string=%~2"
set "string=%string::=-%"
set "string=%string:/=-"
ECHO rename "%~1" "%~n1_%string%%~x1"
pause
goto :eof
:end
NOTE: I disarmed the rename command. Remove the ECHO after troubleshooting, if it works as intended.
#Stephan's answer is probably the best approach. But if you want to change directories ...
The windows shell has a working drive/volume, and on each drive/volume a current working folder. cd changes the working folder on a disk; to change the working folder on a drive (which is not the working drive) and to make that drive the working drive, you need to use cd /d, in this case cd /d "F:\images 2017+".
(A plain cd in this instance changes the working folder on F:\, but if your working folder is on C: -- as I'm guessing is the case -- it will not be changed.)
Assuming command extensions are enabled, you should also be able to use pushd and popd. pushd behaves like cd /d but also saves your previous location; popd returns you to that previous location. (And IIRC pushd will accept UNC paths.)
So at the beginning of your script, pushd "F:\images 2017+", and at the end popd.
I tend to favor pushd/popd over cd because invocations can be nested. So you can do things like
(assume working directory is C:\Users\IoCalisto):
pushd "F:\images 2017+"
(working directory is now F:\images 2017+)
pushd "Z:\images 2015-2016"
(working directory is now Z:\images 2015-2016)
popd
(working directory is now F:\images 2017+)
popd
(working directory is now C:\Users\IoCalisto)
... with this approach, your scripts will have fewer "side effects" and be more modular, or at least modularizable.
I believe a windows update broke my .bat file.
What this .bat file is supposed to do is update files within the folder with a date and time using nircmd.exe.
All file names start with mmddyy for reference.
Here is the .bat file code.
REM #echo on
REM setlocal enabledelayedexpansion
FOR /R C:\Users\USERNAME\Desktop\optimize %%F in (*.*) DO call :Setfiletime %%F
goto End
:Setfiletime
SET FNAME=%~n1
echo %FNAME%
SET MM=%FNAME:~0,2%
SET DD=%FNAME:~2,2%
SET YY=%FNAME:~4,2%
nircmd.exe setfiletime %1 "%DD%-%MM%-20%YY% 18:00:00" "%DD%-%MM%-20%YY%18:00:00"
:goto :eof
:End
REM endlocal
The output now shows each line before :Setfiletime, then ends with REM.
Why is this batch file no longer working and what would I need to do to fix it?
EDIT: Fixed - file was in the wrong location. The simplest solution was the best answer.
I have two folders CopyFrom and CopyTo where CopyFrom has 100 text files named as 1.txt…100.txt and in CopyTo folder I have 100 folders as F1…F100. Now, I want to copy one file from CopyFrom folder to one folder in CopyTo so that F1 will contain 1.txt, F2 will contain 2.txt,…, F100 will contain 100.txt file.
I know to copy all folders I can use something like For /d %%a in (C:\Users\me\Desktop\ShortCuts\*) do xcopy "C:\Users\me\Desktop\Time.xls" "%%a", but I could not find a way to copy different files to different folders.
I can echo all the files (For %%a in (C:\Users\me\Desktop\ShortCuts\*) Echo "%%a") in the CopyFrom folder and also can Echo all the folders in CopyTo folder but could not figure out to working with both to get what I am looking for.
#echo off
setlocal enableextensions disabledelayedexpansion
rem Configure paths
set "copyFrom=c:\somewhere"
set "copyTo=c:\anotherPlace"
rem Generate two lists, one with files and one with folders
dir /b /a-d "%copyFrom%\*" > "%temp%\copyFromFiles.txt"
dir /b /ad "%copyTo%\*" > "%temp%\copyToFolders.txt"
rem Assign each list as input to two streams and start processing
9< "%temp%\copyFromFiles.txt" 8< "%temp%\copyToFolders.txt" (
call :matchFromWithTo
)
rem Remove generated lists
del "%temp%\copyFromFiles.txt"
del "%temp%\copyToFolders.txt"
rem End
goto :eof
:matchFromWithTo
rem Read file from stream 9 and leave if nothing read
<&9 set /p "file=" || goto :eof
rem Read folder from stream 8 and leave if nothing read
<&8 set /p "folder=" || goto :eof
rem Do the copy (debug: we will only echo the command)
echo copy "%copyFrom%\%file%" "%copyTo%\%folder%"
rem Keep reading until all files or folders are processed
goto :matchFromWithTo
Supposing the source location contains the files 1.txt to 100.txt only and the target location already contains all the F1 to F100 directories, the following code snippet might work for you:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "Pattern=*.txt"
set "CopyFrom=."
set "CopyTo=D:\Target"
for %%F in ("%CopyFrom%\%Pattern%") do (
ECHO copy "%%~F" "%CopyTo%\F%%~nF\"
)
endlocal
exit /B
There is no enumeration of the target location done, the copy destination is simply derived from the source file name.
After having tested the script, remove the upper-case ECHO command to actually copy files!
So if I have
/folder/file1.txt
/folder/file2.jpg
/folder/file3.py
I want to create
/folder/file1/file1.txt
/folder/file2/file2.jpg
/folder/file3/file3.py
I have this batch file (be careful where you run it), which mostly works but if there is whitespace in the file name, the folder name will only be named up until the whitespace and so the file won't be moved inside of it.
Also, I only got it to work by arbitrarily putting the word "Folder" or some random string at the end of the folder name, if I exclude that, for some reason it won't work. I'm on windows 7.
#echo off
for /f %%a in ('dir /a-d /b') do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a"
)
goto :EOF
:func
set file=%~1
set dir=%file% Folder
md "%dir%" Folder 2>nul
move "%file%" "%dir%"
goto :EOF
Any ideas on how to address the whitespace/name issues? Thanks in advance.
#echo off
for /f "usebackq delims=?" %%a in (`dir /a-d /b`) do (
if not "%%~dpnxa"=="%~dpnx0" call :func "%%~a"
)
goto :EOF
:func
set file=%~1
set dir=%file% Folder
md "%dir%" Folder 2>nul
move "%file%" "%dir%"
goto :EOF
By setting the delims=? you are saying that your delimiter is a ? to split up a string, instead of the whitespace character, which allows you to read full file names with spaces in them. Usebackq means that you instead use ` around the command to be ran, which to me, just makes it more logical to read and understand "Hey, I'm actually executing this string."
To avoid problems with spaces in paths/file names, double quote all the references to them.
The reason for having to include a string at the end of the folder in your code is you are trying to create a folder with exactly the same name that the file (in your code, you are not removing the extension), and you can not have two elements (files or folders) inside a folder with the same name.
#echo off
for %%a in ("c:\folder\*") do (
if not "%%~fa"=="%~f0" (
if not exist "%%~dpna\" echo md "%%~dpna"
if exist "%%~dpna\" echo move /y "%%~fa" "%%~dpna"
)
)
For each file in the indicated folder
if the file is not the batch file
if not exist a folder with the same name that the file, create it
if the target folder exist, move the file to the folder
%%~fa = full path of the file being processed
%~f0 = full path of the batch file
%%~dpna = drive, path, and file name without extension of the current file being proccesed
In this code, the reason for the third if is to check if the possible previous folder creation has failed. If you have a file with no extension, you will not be able to create the folder, as it will have exactly the same name as the file and this is not allowed.
Code includes echo commands before md and move to show what will be executed. If the output is correct, remove the echo to make it work.
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")