I am trying to write a script to replace old files content with new files content which is appearing in the following format:
Old file : something.txt
New file : something.txt.new
Old file need to replaced with New file contents
New File name to be rename without new
Old file need to be deleted
Below script is not working :Could you please rewrite:
#echo off
setlocal enabledelayedexpansion
set FOLDER_PATH=D:\test
for %%f in (%FOLDER_PATH%*) do if %%f neq %~nx0 (
set basename=test
ren *.txt.new !basename!.txt
)
PAUSE
i have many files in folder and need to iterate through each file,only i need is basename variable need to be filled with the name of the old file name in each iteration
#echo off
setlocal
set FOLDER_PATH=D:\test
for %%f in (%FOLDER_PATH%\*.new) do if "%%~ff" neq "%~f0" (
ECHO move /Y "%%~ff" "%%~dpnf"
)
PAUSE
or
#echo off
setlocal
set FOLDER_PATH=D:\test
for %%f in (%FOLDER_PATH%\*.new) do if "%%~ff" neq "%~f0" (
if exist "%%~dpnf" ECHO del "%%~dpnf"
ECHO rename "%%~ff" "%%~nf"
)
PAUSE
Note that operational move (del and rename) commands are merely ECHOed for debugging purposes.
Also note that if "%%~ff" neq "%~f0" could be omitted iterating *.new files as %~f0 has an extension of .bat or .cmd (try echo %~x0 %~f0).
Resources (required reading):
(command reference) An A-Z Index of the Windows CMD command line
(additional particularities) Windows CMD Shell Command Line Syntax
(%~ff etc. special page) Command Line arguments (Parameters)
(>, 2>&1 etc. special page) Redirection
You missed a \in %FOLDER_PATH%\*.
You want to rename *.new files only, so why not using this pattern rather than *? If you are interested in files matching the pattern *.txt.new, then specify this instead of *.
There is no need for variable basename; simply use %%~nf to remove the (last) suffix (.new).
The ren command throws an error in case the target file already exists; since you want it to be overwritten, use move /Y instead. Add > nul to hide the summary 1 file(s) moved..
Remove the if query after having resolved item 2.
All in all, your script can be reduced to:
#echo off
set "FOLDER_PATH=D:\test"
rem // Ensure to specify the correct pattern, `*.new` or `*.txt.new`:
for %%f in ("%FOLDER_PATH%\*.txt.new") do (
> nul move /Y "%%~f" "%%~nf"
)
pause
Invalid question Invalid answer
source 1
#echo off
set FOLDER_PATH=D:\test
cd /d "%FOLDER_PATH%"
ren "*.txt.new" "*.txt"
source 2
#echo off
set FOLDER_PATH=D:\test
cd /d "%FOLDER_PATH%"
ren "*.txt" "*.txt.new"
Related
I'm trying to create a batch file script that will compress all subfolders named folder1 within a directory, BUT it should only compress this folder if it does NOT contain another subfolder with the same name.
I am very new to cmd and batch files, and this is also my first post of stack overflow, please let me know if I've failed to give some information that I should!
The bit of pseudo-ish code below hopefully illustrates what I'm trying to accomplish:
#echo off
SETLOCAL EnableDelayedExpansion
FOR /D /R %%G IN (*folder1*) DO (
CD %%G
SET /A compress=true
FOR /D /R %%H IN (*folder1*) DO (
ECHO folder contains another folder of same name, should not be compressed
SET /A compress=false
)
IF !compress!==true (
ECHO Run compression operation on folder
"C:\Program Files (x86)\7-zip\7z.exe" a -tzip "%%G.zip" "%%G\"
)
)
Please ask away if anything seems unclear! I'm really hoping to turn the above into functional code, thank you in advance for any input or thoughts.
#ECHO OFF
SETLOCAL
:: Starting directory
SET "sourcedir=U:\sourcedir"
:: name of directory to compress
SET "targetname=targetdir"
FOR /d /r "%sourcedir%" %%a IN (*) DO (
IF /i "%%~nxa" == "%targetname%" IF NOT EXIST "%%a\%targetname%\." (
ECHO compress %%a
rem temporarily switch to target directory
PUSHD "%%a"
ECHO 7z a -tzip "%%a.zip"
rem back to original directory
POPD
)
)
GOTO :EOF
This should do as you want - it will echo not execute the 7z command.
The if sees whether the "name and extension" portion of the directory-name in %%a matches the target (the /i makes the match case-insensitive). If it matches AND there is a subdirectory with the required name, then the compression portion is executed.
There are two points to consider.
First, the name of the destination ZIP file. As you have written it, the ZIP generated would be folder1.zip in the parent directory. IDK what you want here. This code would do the same, but %%a.zip could be replaced by ..\%targetname%.zip since the pushd/popd changes the current directory to the folder1 directory and .. means the parent directory.
The second matter is whether or not you want to compress ...\folder1\folder1 (which would have a destination ZIP file of ...\folder1\folder1.zip)
Revision given comment:
#ECHO OFF
SETLOCAL
:: Starting directory
SET "sourcedir=U:\sourcedir"
:: name of directory to compress
SET "targetname=targetdir"
REM (
FOR /d /r "%sourcedir%" %%a IN (*) DO IF /i "%%~nxa" NEQ "%targetname%" (
rem calculate parent name in %%~nxp and grandparent in %%~nxg
FOR %%p IN ("%%~dpa.") DO FOR %%g IN ("%%~dpp.") DO (
IF /i "%%~nxp" == "%targetname%" IF /i "%%~nxg" NEQ "%targetname%" (
ECHO child %%~nxa
ECHO parent %%~nxp
ECHO Gparent %%~nxg Gppath=%%~dpg
ECHO compress %%a
rem temporarily switch to target directory
PUSHD "%%a"
ECHO 7z a -tzip "%%a.zip"
ECHO -------------------
rem back to original directory
POPD
)
)
)
GOTO :EOF
It's not that clear what you want to do with a directory named ...\folder1\folder1\something or what the target ZIP file-name should be.
The if in the for /d /r line will ensure that only leaf-names that do not match the target name are processed. The path-name in %%a is then processed into the parent and grandparent portions - note that %%~dp? is the drive+path portion of %%? which terminates \ so appending . to this resolves to effectively removing the terminal \ yielding a "filename".
You appear to want to compress directories that have a parent but not a grandparent named with the target string, hence the innermost if statement.
I've just echoed the various strings available at this point so they may be strung together as required to form your destination ZIP file-name. Note that the pushd/popd bracket ensures that the current directory at the time of the compress is the leaf to be compressed.
Hello and firstly I would like to apologize for this post if it was already answered before. I spent the last 4 hours searching Stackoverflow and Google.
I have a gamesettings.ini file I would like to edit via batch file. I need to perform this over many PCs, so I would like to keep the other settings besides 2 lines in the file.
The two lines im trying to change are:
CustomVoiceChatInputDevice=Default Input
CustomVoiceChatOutputDevice=Default Output
I tried a few batch scripts I found on Stackoverflow, but they only work if I define the full line. Since every user has different options set, i need the script to just take the start of the line. Just "CustomVoiceChatInputDevice" for example.
Here's an example code I used, thanks to #jsanchez. This script doesn't work unless I type out the whole line:
Thank you for your time!!
#echo off
::Use the path from whence the script was executed as
::the Current Working Directory
set CWD=C:\
::***BEGIN MODIFY BLOCK***
::The variables below should be modified to the
::files to be changed and the strings to find/replace
::Include trailing backslash in _FilePath
set _FilePath=C:\Users\NEOSTORM\AppData\Local\RedDeadGame\Saved\Config\WindowsClient\
set _FileName=GameUserSettings.ini
::_WrkFile is the file on which the script will make
::modifications.
set _WrkFile=GameUserSettings.bak
set OldStr="CustomVoiceChatInputDevice"
set NewStr="CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game)"
::***END MODIFY BLOCK***
::Set a variable which is used by the
::search and replace section to let us
::know if the string to be modified was
::found or not.
set _Found=Not found
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION
if not exist "%_FilePath%%_FileName%" goto :NotFound
::If a backup file exists, delete it
if exist "%_FilePath%%_WrkFile%" (
echo Deleting "%_FilePath%%_WrkFile%"
del "%_FilePath%%_WrkFile%" >nul 2>&1
)
echo.
echo Backing up "%_FilePath%%_FileName%"...
copy "%_FilePath%%_FileName%" "%_FilePath%%_WrkFile%" /v
::Delete the original file. No worries, we got a backup.
if exist "%_FilePath%%_FileName%" del "%_FilePath%%_FileName%"
echo.
echo Searching for %OldStr% string...
echo.
for /f "usebackq tokens=*" %%a in ("%_FilePath%%_WrkFile%") do (
set _LineChk=%%a
if "!_LineChk!"==%OldStr% (
SET _Found=Found
SET NewStr=!NewStr:^"=!
echo !NewStr!
) else (echo %%a)
)>>"%_FilePath%%_FileName%" 2>&1
::If we didn't find the string, rename the backup file to the original file name
::Otherwise, delete the _WorkFile as we re-created the original file when the
::string was found and replaced.
if /i "!_Found!"=="Not found" (echo !_Found! && del "%_FilePath%%_FileName%" && ren "%_FilePath%%_WrkFile%" %_FileName%) else (echo !_Found! && del "%_FilePath%%_WrkFile%")
goto :exit
:NotFound
echo.
echo File "%_FilePath%%_FileName%" missing.
echo Cannot continue...
echo.
:: Pause script for approx. 10 seconds...
PING 127.0.0.1 -n 11 > NUL 2>&1
goto :Exit
:Exit
exit /b
Each setting within your .ini file identifies the name of the setting. So the order of the lines should not may not matter.
If the line order is meaningless, then all you need do is use FINDSTR /V to remove the old values, and then simply append the new values. In the script below I modify both values at the same time.
#echo off
setlocal enableDelayedExpansion
set "iniLoc=C:\Users\NEOSTORM\AppData\Local\RedDeadGame\Saved\Config\WindowsClient"
set "iniFile=%iniLoc%\GameUserSettings.ini"
set "iniBackup=%iniLoc%\GameUserSettings.bak"
set "CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game)"
set "CustomVoiceChatOutputDevice=Some new value"
>"%iniFile%.new" (
findstr /vb "CustomVoiceChatInputDevice= CustomVoiceChatOutputDevice=" "%iniFile%"
echo CustomVoiceChatInputDevice=!CustomVoiceChatInputDevice!
echo CustomVoiceChatOutputDevice=!CustomVoiceChatOutputDevice!
)
copy "%iniFile%" "%iniBackup%"
ren "%iniFile%.new" *.
It would be slightly faster to create the backup file via rename instead of copy, but then there would be a brief moment where the ini file does not exist.
Windows command processor is not designed for editing text files, it is designed for running commands and applications.
But this text file editing/replacing task can be nevertheless done with cmd.exe (very slow):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileName=%LOCALAPPDATA%\RedDeadGame\Saved\Config\WindowsClient\GameUserSettings.ini"
set "TempFile=%TEMP%\%~n0.tmp"
if not exist "%FileName%" goto EndBatch
del "%TempFile%" 2>nul
for /F delims^=^ eol^= %%A in ('%SystemRoot%\System32\findstr.exe /N "^" "%FileName%"') do (
set "Line=%%A"
setlocal EnableDelayedExpansion
if not "!Line:CustomVoiceChatInputDevice=!" == "!Line!" (
echo CustomVoiceChatInputDevice=Line (Astro MixAmp Pro Game^)
) else if not "!Line:CustomVoiceChatOutputDevice=!" == "!Line!" (
echo CustomVoiceChatOutputDevice=Line (Astro MixAmp Pro Game^)
) else echo(!Line:*:=!
endlocal
) >>"%TempFile%"
rem Is the temporary file not binary equal the existing INI file, then move
rem the temporary file over existing INI file and delete the temporary file
rem if that fails like on INI file currently opened by an application with
rem no shared write access. Delete the temporary file if it is binary equal
rem the existing INI file because of nothing really changed.
%SystemRoot%\System32\fc.exe /B "%TempFile%" "%FileName%" >nul
if errorlevel 1 (
move /Y "%TempFile%" "%FileName%"
if errorlevel 1 del "%TempFile%"
) else del "%TempFile%"
:EndBatch
endlocal
See the answer on How to read and print contents of text file line by line? for an explanation of the FOR loop.
Please note the caret character ^ left to ) in the two lines to output. A closing parenthesis outside a double quoted argument string must be escaped here with ^ as otherwise ) would be interpreted by Windows command processor as end of command block and not as literal character to output by command ECHO. Other characters with special meaning for cmd.exe on parsing a command line or an entire command block like &|<> must be also escaped with ^ on ECHO command lines.
Please take also a look on Wikipedia article about Windows Environment Variables. It is highly recommended to use the right predefined environment variables for folder paths like local application data folder.
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.
call /? ... explains %~n0 ... batch file name without path and file extension.
del /?
echo /?
endlocal /?
fc /?
findstr /?
for /?
if /?
move /?
rem /?
set /?
setlocal /?
I have a batch script which accepts >=1 files via drag & drop. The full paths are kept in an array and later fed to another program as input. The file name+extension is kept in another array which is then shown to the user.
I am trying to check the file extension and if it is not .bin, automatically rename the file I dragged & dropped to .bin and reload it to be added to the two arrays. How can I do that? I have tried some if commands or %%~xi but usually it doesn't properly detect if it's .bin or not and of course the path is not updated at the array.
#echo off
pushd %~dp0
setlocal enabledelayedexpansion
set /a Count = 0
:START
set file="%~1"
if %file%=="" goto RUN
for %%i in (%file%) do set name=%%~nxi
set /a Count += 1
set [FilePath.!Count!]=%file%
set [FileName.!Count!]=%name%
shift
goto START
:RUN
for /l %%i in (1, 1, %Count%) do (
program.exe -command "![FilePath.%%i]!"
echo.
echo File Name: ![FileName.%%i]!
echo.
pause
cls
if exist file.log del file.log
)
You could just rename it during your array population. There are a few other potential problems with your script (such as pushd to an unquoted directory, delayedexpansion where you don't need it where it will potentially clobber filenames containing exclamation marks, and if %file%=="" should have "%file%" quoted). And there's really no reason to maintain an array of filenames or loop twice. Your script is much more complicated than it needs to be.
#echo off
setlocal
pushd "%~dp0"
for %%I in (%*) do (
if /I not "%%~xI"==".bin" move "%%~fI" "%%~dpnI.bin" >NUL
program.exe -command "%%~dpnI.bin"
echo;
echo File Name: "%%~nxI"
echo;
rem If you want to rename the file back the way it was after running
rem program.exe on it, uncomment the following line:
rem if /I not "%%~xI"==".bin" move "%%~dpnI.bin" "%%~fI" >NUL
pause
cls
if exist file.log del file.log
)
I've been trying to get the syntax right, but I'm having issues. Not only am I not getting the syntax right, but I would like this script to:
Locate all files of a certain criteria on All Drives in a network
check to see if the file is the updated file (or new file)
if it is NOT the new or updated file, locate the new file and replace it
ALSO! If I can get this to work on a schedule, such as every 6 hours... that would be a real help
I got this code to work once, but I changed it a couple times and saved over it.
#echo off
SETLOCAL
cls
:locate_old
for /d /r Z:\ %%a in (*) do if exist "%%~fa\old.file" set "oldFile=%%~fa\old.file"
if not defined oldFile (
echo old file not found...
) else (
echo old file found&GOTO oldFileCheck
)
:oldFileCheck
find "old file text" "%oldFile%" && echo old file is already updated || GOTO findNewFile
:findNewFile
for /d /r Z:\ %%a in (*) do if exist "%%~fa\new.file" set "newFile=%%~fa\new.file"
if not defined newFile (
echo no new file detected...
) else (
echo new file located...&GOTO fileSwap
)
:fileSwap
copy /y "%newFile%" "%oldFile%" && echo file updated || file not updated
If I understand your requirement, you want to replace all "old.file" files on Z:\ with "new.file" files if they aren't updated already. This is untested:
#if not defined debug_batch_files echo off
REM You can set debug_batch_files to 1 and quickly see verbose execution
pushd Z:\
for /f "delims=" %%a in ('dir /b /s /a-d new.file') do echo xcopy /D /Y "%%~fa" "%%~dpaold.file"
REM Remove "echo" from the above line if it displays the right paths.
popd
I have several folders that have files with double file extensions along with regular file extensions. I need to create a batch script to search all the folders and remove the last extension with any files that have double extensions. None of the file extensions are consistent.
Here's an example
C:\test\regular.exe
C:\test\picture.jpg.doc
C:\newtest\document.doc.pdf
End Result I need
C:\test\regular.exe
C:\test\picture.jpg
C:\newtest\document.doc
#ECHO OFF
SETLOCAL
SET sourcedir=c:\sourcedir
FOR /r "%sourcedir%" %%i IN (*.*) DO (
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF NOT EXIST "%%~dpni" ECHO REN "%%~fi" "%%~ni"
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF EXIST "%%~dpni" ECHO CAN NOT REN "%%~fi" "%%~ni"
)
GOTO :EOF
This batch should accomplish the task.
For each file in the tree rooted at sourcedir, if the NAME of the file itself contains an 'extension' and the filename without the original extension does not exist, then rename the file. That way, if ...picture.jpg.doc is found, the rename should occur only if ...picture.jpg does not exist.
The command to rename is simply ECHOed. You'd need to remove the ECHO keyword to activate the rename - after verifying that's what you want to do.
I've added a second line to report that a rename could not be done because of an existing file.. This could be done very slightly better, but it will work.
Revised to modify name in case simple rename can not be done.
Caution - this version will rename immediately - there are no ECHOes to provide a list first because it's nonsense to provide such a list when renaming a file may produce different results on the main rename run.
#ECHO OFF
SETLOCAL
SET sourcedir=c:\sourcedir
FOR /r "%sourcedir%" %%i IN (*.*) DO (
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF EXIST "%%~dpni" (
SET renreq=Y
FOR %%a IN (new alt extra another 1 2 3 4 5 6 7 8 9) DO IF DEFINED renreq (
IF NOT EXIST "%%~dpi%%~nn_%%a%%~xn" (
REN "%%~fi" "%%~nn_%%a%%~xn"
SET "renreq="
)
)
IF DEFINED renreq ECHO CAN NOT REN "%%~fi"
) ELSE (
REN "%%~fi" "%%~ni"
)
)
GOTO :EOF
Reasonably obviously, the list of "extras" can be extended if required.
Try this and remove the echo, if the output is OK:
#echo off &setlocal
for /r \ %%i in (*) do (
for %%j in ("%%~ni") do if "%%~xj" neq "" echo ren "%%~fi" "%%~nj"
)
Edit: added support for the entire HD.