getting syntax error when trying to run ren command - batch-file

I am trying to build my software using cx_freeze for which I built a bat file that runs the build command so when the build is completed it generates build directory inside which there is another directory exe.win-amd64-3.6 containing the bundled code. inside which there is lib/scipy/spatial/cKDTree.cp36-win_amd64.pyd now this file has to be renamed as ckdtree.cp36-win_amd64.pyd for the build to run. I am trying to automate this by including rename in batch file but it's giving error.
I am trying to run rename command when build is completed but it's not working i get the error the syntax is incorrect. i tried to remove
%~dp0
even this didn't work
#ECHO OFF
Set "FRAS_Folder=%~dp0build_logs\FRAS"
If Not Exist "%FRAS_Folder%" MD "%FRAS_Folder%"
Call :Gen_Report_Name fras_logname
echo FileName : "%fras_logname%"
echo Absolute PathName : "%FRAS_Folder%\%fras_logname%"
REM Example save the result of this command with a log file into this folder
python setup.py build>"%FRAS_Folder%\%fras_logname%"
#REM rename the scipy.spatial.cKDtree file to scipy.spatial.ckdtree in lib/scipy/spatial
#REM rename the file cKDTree.cp36-win_amd64.pyd to ckdtree.cp36-win_amd64.pyd in lib/scipy/spatial
ren "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\cKDTree.cp36-win_amd64.pyd" "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.pyd"
pause & exit /b
:::::::::::::::::: FUNCTION :::::::::::::::::::
:Gen_Report_Name <file_with_date to be set>
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set "dt=%%a"
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set "stamp=%YYYY%%MM%%DD%_%HH%%Min%%Sec%"
Set "%1=%stamp%.log"
Exit /b
::------------------------------------------------------------------------------------
Kindly help me figure what's the issue!

You are using the wrong syntax for the ren command. See ren /?
The second filename must be a filename without path.
If you prefer to include the path for the second filename use the move command.

Windows is case insensitive so the files are having the same name. You will need to use an intermediate filename to change the case of the filename.
Try this:
ren "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\cKDTree.cp36-win_amd64.pyd" "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.tmp"
ren "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.tmp" "%~dp0build\exe.win-amd64-3.6\lib\scipy\spatial\ckdtree.cp36-win_amd64.pyd"

Related

Am I the only one who have this problem: While running something like .bat, the "X:\..\..path" often becomes ""X:\..\path and producing errors?

While running something like .bat, the "X:\..\..path" often becomes ""X:\..\path and producing errors. For example, I was installing apktool, then it just appeared this:
'""C:\Program' is not recognized as an internal or external command,
operable program or batch file.
I then copy the command and put one of the double quote to the end, which is like this: "C:\Program"
And everything just went smoothly, installation was successful. Then I tried to decode an apk, and the exactly same problem occurred: '""C:\Program' is not recognized as an internal or external command, operable program or batch file. This time I have no idea how to fix it, it's not like the .bat now, I cannot get the #echo on and copy the last command and edit it. So I am here to ask: If I am the only one who met this? Any way to fix this? Thank you.
My command:
apktool d test.apk
Image of running a decode command : 1
apktool.bat content:
#echo off
setlocal
set BASENAME=apktool_
chcp 65001 2>nul >nul
set java_exe=java.exe
if defined JAVA_HOME (
set java_exe="%JAVA_HOME%\bin\java.exe"
)
rem Find the highest version .jar available in the same directory as the script
setlocal EnableDelayedExpansion
pushd "%~dp0"
if exist apktool.jar (
set BASENAME=apktool
goto skipversioned
)
set max=0
for /f "tokens=1* delims=-_.0" %%A in ('dir /b /a-d %BASENAME%*.jar') do if %%~B gtr !max! set max=%%~nB
:skipversioned
popd
setlocal DisableDelayedExpansion
rem Find out if the commandline is a parameterless .jar or directory, for fast unpack/repack
if "%~1"=="" goto load
if not "%~2"=="" goto load
set ATTR=%~a1
if "%ATTR:~0,1%"=="d" (
rem Directory, rebuild
set fastCommand=b
)
if "%ATTR:~0,1%"=="-" if "%~x1"==".apk" (
rem APK file, unpack
set fastCommand=d
)
:load
"%java_exe%" -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0%BASENAME%%max%.jar" %fastCommand% %*
rem Pause when ran non interactively
for /f "tokens=2" %%# in ("%cmdcmdline%") do if /i "%%#" equ "/c" pause
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.
set java_exe="%JAVA_HOME%\bin\java.exe"
Should be
set "java_exe=%JAVA_HOME%\bin\java.exe"
(apply this principle throughout your code)
Then, if you require " anywhere, insert it where it's needed - don't try to include it as part of a variable's value.
This should clean up at least some of your problems.

appending date with filename using batch scripts

I am trying to set a housekeeping for different type of file. PFB scenario.
I have below set of files in a network path(\NAS.domain.local\data\Arasan)
test.sql
test1.txt
test2.log
I am trying to rename the files as shown below and move the files to .\Archive\ directory
Test_15-12-2016_151428.sql
Test1_15-12-2016_151428.txt
Test_15-12-2016_151428.log
([Filename]_DD-MM-YYYY_HHMISS.[ext])
I have built the below batch script.
#echo ON
SET Log_Path=\\NAS.domain.local\data\Arasan
SET Script_Path=C:\Scripts
REM ###########################################REM
REM ## Do make any changes to the text below ##REM
REM ###########################################REM
cd %Script_Path%
pushd %Log_Path%
dir /b /a-d > %Script_Path%\list.txt
set HH=%TIME:~0,8%
for /F %%A in (%Script_Path%\list.txt) do (
setlocal EnableExtensions EnableDelayedExpansion
set ffname=%%A
set "fname=%%~nA"
set "fext=%%~xA"
ren !ffname! !fname!_%DATE%_%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%!fext!
endlocal
)
del %Script_Path%\list.txt
move *.* Archive\
popd
exit
Now my issue is it is working perfectly in my machine but when I transfer this to server and execute. It is
throwing "The syntax of the command is incorrect." Error.
And it is moving the files without renaming. As for as i know, file name and extension is not being assigned to the variable properly in below part
set ffname=%%A
set "fname=%%~nA"
set "fext=%%~xA"
Server OS: Windows server 2008 R2 Standard(SP1)
Can anyone please help me. Thanks a lot.
Here is the part of the code you should be using to get a consistent date and time output:
For /F "Skip=1" %%A In ('WMIC OS GET LocalDateTime') Do For %%B In (%%~nA
) Do Set "DTS=%%B"
Set "DTS=_%DTS:~6,2%-%DTS:~4,2%-%DTS:~,4%_%DTS:~-6%"
Echo( [%DTS%]
Pause
Just incorporate this into the rest of your codeā€¦

CMD trying to set variable in a loop

I'm working with windows' cmd and trying to set a variable in a loop. Here's the code I have:
for /d %%a in ("F:\backup*") do set folder=%%a
ECHO %folder%
PAUSE
I want to look for a folder with name starting with "backup" on drive F and save that folder's name to %folder% variable. So for example if the folder would be called "backup 2017-01-18" I'd like that saved to a var.
Instead it doesn't seem to set anything as the ECHO just prints that "ECHO is on". The for loop is correct and the folder is there as well (I'm already using that piece of code for other batch with robocopy).
I could theoretically put all my code inside the FOR loop and use %%a instead of the %folder% var but that seems like a hacky solution.
All the solutions I found so far pointed to using EnableDelayedExpansion. I modified the code to use it like that:
Setlocal EnableDelayedExpansion
for /d %%a in ("F:\backup*") do set folder=%%a
ECHO !folder!
PAUSE
But now ECHO prints "!folder!" as if it would not detect the variable. If I revert to ECHO %folder% I once again learn that "ECHO is on".
EDIT:
I found the issue here. I was also running another batch file on the backup folder. It turns out that ROBOCOPY (which I used in that batch) is setting the enclosing folder to hidden, system and readonly by default (even if copied files are not hidden or system o_0). When I removed HSR attributes on the directory the code posted here started working fine (the initial version).
If your loop for /d %%a in ("F:\backup*") do does not detect any directories whose names begin with backup, they either do not exist or there are the attributes hidden and/or system set.
To detect also such hidden or system directories, replace the for /D loop by this:
rem Change to parent directory "F:\" temporarily in order for the `~f` modifier to resolve the full path properly:
pushd "F:\" || exit /B 1
for /F "eol=| delims=" %%D in ('dir /B /A:D /O:N "backup*"') do set "folder=%%~fD"
popd

Why are other folder paths also added to system PATH with SetX and not only the specified folder path?

I have a batch file which I am calling from C++ using system("name.bat"). In that batch file I am trying to read the value of a registry key. Calling the batch file from C++ causes set KEY_NAME=HKEY_LOCAL_MACHINE\stuff to fail.
However, when I directly run the batch file (double clicking it), it runs fine. Not sure what I am doing wrong.
Batch file:
set KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\Ansoft\Designer\2014.0\Desktop
set VALUE_NAME=InstallationDirectory
REG QUERY %KEY_NAME% /v %VALUE_NAME%
C++ file:
int main(void)
{
system("CALL C:\\HFSS\\setup_vars.bat");
return 0;
}
UPDATE 1:
I found out that the key is actually in the 64-bit registry, and I was building my C++ solution as a 32-bit. Once I fixed that, it found the registry key fine.
Now I am having an issue adding that path to my PATH variable. Instead of creating a system variable, it is creating a user variable PATH and adding it there.
Running from command line works.
Code:
set KEY_NAME=HKLM\SOFTWARE\Ansoft\Designer\2014.0\Desktop\
set VALUE_NAME=InstallationDirectory
FOR /F "usebackq skip=1 tokens=1,2*" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME%`) DO (
set ValueName=%%A
set ValueType=%%B
set ValueValue=%%C
)
if defined ValueName (
#echo Value Value = %ValueValue%
) else (
#echo %KEY_NAME%\%VALUE_NAME% not found.
)
:: Set PATH Variable
set path_str=%PATH%
set addPath=%ValueValue%;
echo %addPath%
echo %ValueValue%
echo %PATH%| find /i "%addPath%">NUL
if NOT ERRORLEVEL 1 (
SETX PATH "%PATH%
) else (
SETX PATH "%PATH%;%addPath%;" /M
)
UPDATE 2:
I moved the placement of the option /M and it is now adding to right PATH variable.
However, when I am doing this, it is adding the PATH more than once (3 times) and then it is also adding a path to visual studio amd64 folder.
I'm mot sure why that is happening.
Windows creates a copy of the entire environment table of the process starting a new process for the new process. Therefore on start of your C++ application, your application gets the environment table including PATH from parent process, Windows Explorer or in your case Visual Studio. And this PATH is copied for cmd.exe on start of the batch file.
Taking the entire process tree into account from Windows desktop to the batch file, there have been many copies made for PATH and some processes perhaps appended something to their local copy of PATH like Visual Studio has done, or have even removed paths from PATH.
What you do now with SETX PATH "%PATH% is appending the local copy of PATH modified already by the parent processes in process tree completely to system PATH without checking for duplicate paths.
Much better would be to throw away all code using local copy of PATH and instead read the value of system PATH, check if the path you want to add is not already in system PATH and if this is not the case, append the path you want to add to system PATH using setx.
And this should be done without expanding the environment variables in system PATH like %SystemRoot%\System32 to C:\Windows\System32.
UPDATE
Here is the batch code required for your task tested on Windows 7 x64 and Windows XP x86.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "KeyName=HKLM\SOFTWARE\Ansoft\Designer\2014.0\Desktop"
set "ValueName=InstallationDirectory"
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "%KeyName%" /v "%ValueName%" 2^>nul') do (
if /I "%%N" == "%ValueName%" (
set "PathToAdd=%%P"
if defined PathToAdd goto GetSystemPath
)
)
echo Error: Could not find non-empty value "%ValueName%" under key
echo %KeyName%
echo/
endlocal
pause
goto :EOF
:GetSystemPath
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^>nul') do (
if /I "%%N" == "Path" (
set "SystemPath=%%P"
if defined SystemPath goto CheckPath
)
)
echo Error: System environment variable PATH not found with a non-empty value.
echo/
endlocal
pause
goto :EOF
:CheckPath
setlocal EnableDelayedExpansion
rem The folder path to add must contain \ (backslash) as directory
rem separator and not / (slash) and should not end with a backslash.
set "PathToAdd=%PathToAdd:/=\%"
if "%PathToAdd:~-1%" == "\" set "PathToAdd=%PathToAdd:~0,-1%"
set "Separator="
if not "!SystemPath:~-1!" == ";" set "Separator=;"
set "PathCheck=!SystemPath!%Separator%"
if "!PathCheck:%PathToAdd%;=!" == "!PathCheck!" (
set "PathToSet=!SystemPath!%Separator%!PathToAdd!"
set "UseSetx=1"
if not "!PathToSet:~1024,1!" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%\System32\setx.exe Path "!PathToSet!" /M >nul
) else (
set "ValueType=REG_EXPAND_SZ"
if "!PathToSet:%%=!" == "!PathToSet!" set "ValueType=REG_SZ"
%SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /f /v Path /t !ValueType! /d "!PathToSet!" >nul
)
)
endlocal
endlocal
The batch code above uses a simple case-insensitive string substitution and a case-sensitive string comparison to check if the folder path to append is present already in system PATH. This works only if it is well known how the folder path was added before and the user has not modified this folder path in PATH in the meantime. For a safer method of checking if PATH contains a folder path see the answer on How to check if directory exists in %PATH%? written by Dave Benham.
Note 1: Command setx is by default not available on Windows XP.
Note 2: Command setx truncates values longer than 1024 characters to 1024 characters.
For that reason the batch file uses command reg to replace system PATH in Windows registry if either setx is not available or new path value is too long for setx. The disadvantage on using reg is that WM_SETTINGCHANGE message is not sent to all top-level windows informing Windows Explorer running as Windows desktop and other applications about this change of system environment variable. So the user must restart Windows which is best done always onĀ changing something on persistent stored Windows system environment variables.
The batch script was tested with PATH containing currently a folder path with an exclamation mark and with a folder path being enclosed in double quotes which is necessary only if the folder path contains a semicolon.
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.
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
reg /? and reg add /? and reg query /?
set /?
setlocal /?
setx /?

How to use batch job to add the file "create date" into all the files in a directory?

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")

Resources