Batch script to find the names of modified files - batch-file

I have some 500 .txt files in a folder. Of them, some 100 files contain a text that I wish to change. I have used the below code to do that.
used Repl.bat and the below code:
for %%F in (*.txt) do (
type "%%F"|repl Apples Mangoes >"%%F.new"
move /y "%%F.new" "%%F"
)
Since this searches through all the files, the files are getting modified. I am unable to know in which files, the text has been replaced.
My actual task is to change the string and get the modified files into another folder.
I tried using the below code to move the modified files. but since all the files are getting modified, I am clueless as what to do.
ECHO OFF
set source=C:\abc\
set destination=C:xyz\
for /F "tokens=2-4 delims=/ " %%i in ('date /t') do set yyyymmdd1=%%j"."%%i"."%%k
if exist %destination% goto GO
:GO
mkdir %destination%%yyyymmdd1%
xcopy %source%* %destination% /m/s/d/y/c/v/r
echo.
echo Finished copying %source% to %destination%
echo.
echo Created %destination%%yyyymmdd1%
pause
Thanks in advance

To simply find out what files actually have been modifed, with respect to their contents only, you can use the following code snippet, which collects all the modified files in the log file change.log:
#echo off
> "change.log" (
for %%F in ("*.txt") do (
type "%%~F" | > "%%F.new" repl Apples Mangoes
> nul fc /L "%%~F" "%%~F.new" || echo "%%~F"
> nul move /Y "%%~F.new" "%%~F"
)
)
This uses the fc command and the fact that it sets the ErrorLevel to 0 for matching files, and to 1 otherwise. || constitutes a conditional command separator which executes the next command only in case of a non-zero ErrorLevel (also known as exit code or return code).
The comparison is done in text mode. To change it to binary mode, replace fc /L by fc /B.
The redirection > nul avoids any messages of fc (like Comparing files [...], FC: no differences encountered) or move (like 1 file(s) moved.). If you want to see sch messages on screen, replace the > nul by > con.
To move the collected modified files afterwards, use the following command line in a batch script:
for /F "delims=" %%I in ("change.log") do (move "%%~I" "\path\to\destination\")

Related

Comparing the contents of two recently created folders using Windows Batch file

I'm writing a batch file to compare the contents of two folders on a network drive. A new folder is generated every night by a macro and I want to see what changed between today and yesterday. For example, if yesterday's folder is called "B" and today's folder is "A" and their structure looks like:
- Home
- A
- file1.txt
- file2.txt
- file4.txt
- B
- file1.txt
- file2.txt
- file3.txt
I would want to see something like
A: file4.txt added
A: file3.txt removed
But the format of the output doesn't really matter at the end of the day. I just need to see a comparison of the folder's contents.
What I have so far
Using my limited batch knowledge, I've smashed together this currently non-working solution:
#ECHO OFF
setlocal EnableDelayedExpansion
pushd "\\domain\path\to\Home"
set "j=0"
set "count=2"
:: get the names of the two most recently added folders
FOR /f "delims=" %%i IN ('dir /AD-H /B /O-D') DO (
set /A j=j+1
if !j! equ 1 (
:: send contents of newest folder to file
dir !i! /B > newest_folder.txt
)
if !j! equ 2 (
:: send contents of second-newest folder to file
dir !i! /B > older_folder.txt
)
if !j! geq !count! (
:: break after two folders
goto :end
)
)
:end
fc newest_folder.txt oldest_folder.txt
PAUSE
I saw a similar solution here:
(for %%i in ("folder2\*") do if exist "folder1\%%~nxi" echo(%%~i)>file.csv
But it wouldn't work in my case because the folder names change every day.
Any help would be appreciated!
#ECHO OFF
setlocal EnableDelayedExpansion
set "later="
set "earlier="
pushd "\\domain\path\to\Home"
:: get the names of the two most recently added folders
FOR /f "delims=" %%i IN ('dir /AD-H /B /O-D') DO (
if defined later set "earlier=%%i"&goto report
set "later=%%i"
)
:report
if defined earlier (
dir /b "%earlier%">older.txt
dir /b "%later%">newer.txt
fc older.txt newer.txt
) else echo too few directories found
pause
popd
would be my approach, setting later and earlier to the names of the first two directories found by the dir command.
---- afterthought
if the fc command is replaced by
echo files added
findstr /x /v /g:"older.txt" "newer.txt"
echo files deleted
findstr /x /v /g:"newer.txt" "older.txt"
then your report should be more easily interpreted.
findstr options /x does an exact match, /v reports NON-matches and /g:filename specifies a file containing strings against which to match.

searching for text file(s) and adding a line in them with batch file

I am trying to write a batch file that can be used for the following task - search for certain text files and adding a text line in them - below the specified line. I am trying to use the following approach:
dir /s /a /b "%SystemDrive%\config*.ini" >> %userprofile%\temp.txt
for /F "tokens=* delims=," %%G IN (%userprofile%\temp.txt) DO (echo "%%G" >> %userprofile%\temp2.txt)
for /F "tokens=* delims=," %%G IN (%userprofile%\temp2.txt) DO (
SETLOCAL ENABLEDELAYEDEXPANSION
cd %%~dG%%~pG
set inputFile=%%~nG%%~xG
set outputFile=in.tmp
set _strInsert=TCPPortNumber=870
set _strFind=Random=No
FOR /F "usebackq delims=" %%A IN ("%inputFile%") DO (
Echo %%A | Find "%_strFind%" && ECHO %%A>>"%outputFile%" && ECHO %_strInsert%>>"%outputFile%"
IF [!errorlevel!] == [1] ECHO %%A>>"%outputFile%"
)
MOVE /Y "%outputFile%" "%inputFile%" && DEL /F /Q "%outputFile%"
Searching for config*.ini file(s) and writing results into temp.txt. Inserting quotes in case there are spaces in file paths for each line in temp.txt -> temp2.txt. Then for each file path in temp2.txt trying to insert TCPPortNumber=870 below the line Random=No. If I use a "hard" file path this approach works, but with reading the files path from temp2.txt it gives me an error: The system cannot find the file specified.
Can anyone help?
SETLOCAL ENABLEDELAYEDEXPANSION
dir /s /a /b "%SystemDrive%\config*.ini" >> %userprofile%\temp.txt
set outputFile=in.tmp
set _strInsert=TCPPortNumber=870
set _strFind=Random=No
for /F "usebackqdelims=" %%G IN ("%userprofile%\temp.txt") DO (
pushd %%~dpG
FOR /F "usebackq delims=" %%A IN ("%%~nxG") DO (
ECHO %%A>>"%outputFile%"
Echo %%A | Find "%_strFind%" && >>"%outputFile%" ECHO %_strInsert%
)
MOVE /Y "%outputFile%" "%%~nxG"
popd
)
endlocal
The setlocal command should not be within the loop (unless it is matched by an endlocal) because it is not a switch, but establishes a frame, hence within the loop, cmd is establishing many nested local environments.
The three constant strings also should appear outside of the loop since their values do not change.
The second tempfile is not required as it is simply the first with each line quoted.
Since %temp% may contain spaces, the for/f ... %%Gneeds to have the filename quoted, and consequently theusebackqoption. The line is to be accepted into%%Gin its entirity, sodelims=` is required, turning delimiters off.
The substring selectors may be combined, so ~dp delivers the drive and path and ~nx the name and extension.
In the original code, inputfile was being set up, but %inputfile% would be resolved to the value of inputfile at the time the entire block (parenthesised sequence of lines) was parsed not at run-time as the values change through execution of the code. This is the commonly-encountered delayed expansion problem - hundreds of references here on SO.
Since what appears to be needed is to insert a line after a particular line, we can simply reproduce each line then see whether the insertion is required, which simplifies the code. The placement of the redirector to before the echo overcomes the Windows-NT characteristic of selecting the device to be redirected by preceding the redirector with a device number.
Finally, move /y forces the replacement of the input file with the output file, so the output file will no longer exist
I haven't actually tried this code - you should execute it against a small copied subtree of the real data and evaluate it before relying on it.
small fix - changed original cd to pushd and added corresponding popd also removed superfluous %
PUSHD changes the current directory to that specified. POPD restores the original current-directory.
The extra % was a keying error (my normal machine is ill and I have to use the laptop - and boy, do I loathe the keyboard...)

Replace old file with new file

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"

How to replace #DLOG_ETS=ON by #DLOG_ETS=OFF in all *.opr and *.eng files?

I've created a simple batch file that searches in files with extension .opr and .eng for the term #DLOG_ETS and replace it with #DLOG_ETS=OFF. This may be redundant for cases where the full string is #DLOG_ETS=OFF.
I want to add the condition that only if the string #DLOG_ETS=ON is present, then I want to replace that with #DLOG_ETS=OFF. Otherwise, I want to leave it as it is, i.e. #DLOG_ETS=OFF without making any changes on those .opr or .eng files.
for %%F in (*.opr *.eng) do (
type "%%F"| findstr /v #DLOG_ETS= >"%%F.new"
#echo #DLOG_ETS=OFF >> "%%F.new"
move /y "%%F.new" "%%F"
)
#ECHO Off
SETLOCAL
for %%F in (*.opr *.eng) do (
findstr /v /L "#DLOG_ETS=ON" "%%F" >"%%F.new"
fc "%%F" "%%F.new" >nul
IF ERRORLEVEL 1 (
echo #DLOG_ETS=OFF>>"%%F.new"
move "%%F.new" "%%F"
) ELSE (
DEL "%%F.new"
)
)
GOTO :EOF
For each file, create a new file, removing the line containing the target string. Compare the before and after versions. If there is a difference therefore the string was removed, so append the required line. If no difference, simply delete the new file.
Batch isn't predestined to do text file editing.
A lot of poison chars have to be circumvented.
Vbscript /jscript/PowerShell are all better suited to this task.
Here a batch which calls a sub to get help with Powershell.
You need do adapt the path to your environment.
#Echo off
PushD "X:\Path\to\your\folder"
Set "Srch=#DLOG_ETS=ON"
Set "Repl=#DLOG_ETS=OFF"
Set "Opt=-nologo -noprofile -command"
for %%F in (*.opr *.eng
) do findstr /I "%Srch%" "%%~fF" >NUL 2>&1 && Call :PoSh "%%~fF"
PopD
Goto :Eof
:PoSh
PowerShell %Opt% "& {(GC %1).replace('%Srch%','%Repl%')|Set-Content %1}"

Dynamic Locate All Files and replace with specific file script

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

Categories

Resources