run a script to rename several words in a txt file - string

I need your help.
I have a txt file in a directory (folder) and need to run a script to rename several words, eg.
where LX4XAB to LX4xab
and where is XS3X44 to Xs3x44
and another word
until the end save the file with another name.
Can you help me? Thank you.

Here you go:
#echo off
setlocal enabledelayedexpansion
(for /f "tokens=*" %%f in (input1.txt) do (
set "line=%%f"
set "line=!line:LX4XAB=LX4xab!"
set "line=!line:XS3X44=Xs3x44!"
echo(!line!
)) > newfile.txt
Revision 1
Here is how you can do it with multiple files and doing the naming the way you asked for.
#echo off
setlocal enabledelayedexpansion
cd /d C:\Temp
for %%a in (*.txt) do (
echo %%~nxa|Find /i "_new">nul
if errorlevel 1 (
(for /f "tokens=*" %%f in (%%a) do (
set "line=%%f"
set "line=!line:LX4XAB=LX4xab!"
set "line=!line:XS3X44=Xs3x44!"
echo(!line!
)) > %%~na_new.txt
)
echo %%~nxa|Find /i "_new">nul
if errorlevel 1 ren %%~nxa %%~na.old
)

Related

Selecting x unique random files from a folder and its subfolders with a batch file

I've got some batch code that selects three random files from a folder (and its subfolders), but it's possible for it to end up selecting the same file more than once. I'd like it to always select unique files.
It creates a temporary text file with all the options, so I've tried to get it to remove the selected line and subtract one from the total file count each time one is selected, so that it's removed from the pool of options.
Here's the whole thing:
#echo off
setlocal
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
set "tempFileTwo=%temp%\%~nx0_fileList2_%time::=.%.txt"
pushd %1
dir /b /s /a-d *.mov *.mp4 | findstr /n "^" >"%tempFile%"
popd
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
for /l %%N in (1 1 3) do call :openRandomFile
:: Delete the temp files
del "%tempFile%"
del "%tempFileTwo%"
exit /b
:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do (
start "" "%%B"
echo Selection: %%B
set /a cnt -= 1
findstr /l /v "%%B" "%tempFile%" > "%tempFileTwo%"
copy /y "%tempFileTwo%" "%tempFile%"
)
exit /b
The part that doesn't work is:
findstr /l /v "%%B" "%tempFile%" > "%tempFileTwo%"
copy /y "%tempFileTwo%" "%tempFile%"
I was hoping my findstr would find the selected file and remove it, and copy everything else over, but it apparently matches everything and copies a totally blank file. Not sure what I'm doing wrong.
The %RANDOM% number may return duplicates, which we have to account for. The following adaptation of your code retries to select a random file when an already chosen one would have to be returned:
#echo off
rem // Explicitly preset configuration:
setlocal EnableExtensions DisableDelayedExpansion
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
set "tempFileTwo=%temp%\%~nx0_fileList2_%time::=.%.txt"
rem // Improve quotation and regard failure if `%1` does not point to a directory:
pushd "%~1" && (
dir /b /s /a-d *.mov *.mp4 | findstr /n "^" > "%tempFile%"
popd
) || del "%tempFile%" 2> nul
:: Count the files
set "cnt=0" & for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set "cnt=%%N"
rem // Regard case when there are less than three files:
set "num=3" & if %cnt% lss 3 set "num=%cnt%"
for /l %%N in (1 1 %num%) do call :openRandomFile
:: Delete the temp files
del "%tempFile%"
del "%tempFileTwo%"
endlocal
exit /b
:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
(for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do (
echo Selection: %%B
start "" "%%B"
set /a "cnt -= 1"
rem /* Ensure to match the whole line, including the colon-separated count prefix,
rem and escape `findstr` meta-characters to prevent wrong matches: */
set "LINE=%%A:%%B"
setlocal EnableDelayedExpansion
set "LINE=!LINE:\=\\!" & set "LINE=!LINE:.=\.!"
set "LINE=!LINE:[=\]!" & set "LINE=!LINE:]=\]!"
set "LINE=!LINE:^=\^!" & set "LINE=!LINE:$=\$!"
findstr /V /X /I /C:"!LINE!" "!tempFile!" > "!tempFileTwo!"
endlocal
copy /y "%tempFileTwo%" "%tempFile%"
)) || (
rem /* Detect if `for /F` loop did not iterate, meaning that an already selected
rem file would have become chosen once again, hence retry random selection: */
goto :openRandomFile
)
exit /b
However, I would choose another strategy to get files without duplicates, namely, to build a list of files with each one preceded with a random number, then sorting that list by said numbers and eventually taking the first few elements from the list.
Here is a possible implementation, using a temporary file to build the list:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_TMPF=%TEMP%\%~nx0_%RANDOM%.lst"
rem // Change into target directory:
pushd "%~1" && (
rem // Write to temporary file:
> "%_TMPF%" (
rem // Build list of matching files with a random number preceded:
for /F "delims=" %%F in ('dir /S /B /A:-D-H-S "*.mov" "*.mp4"') do (
set "FILE=%%F"
setlocal EnableDelayedExpansion
echo/!RANDOM!:!FILE!
endlocal
)
)
rem // Sort list of files by preceding random numbers:
sort "%_TMPF%" /O "%_TMPF%"
rem // Read from temporary file:
< "%_TMPF%" (
rem // Fetch the first three items from the list of files:
setlocal EnableDelayedExpansion
for /L %%I in (1,1,3) do (
set /P FILE="" && (
echo Selection: !FILE:*:=!
start "" "!FILE:*:=!"
)
)
endlocal
)
rem // Return from target directory:
popd
rem // Clean up temporary file:
del "%_TMPF%" 2> nul
)
endlocal
exit /B
This is another possible approach, using variables like $FILES[] that constitute a pseudo-array:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Change into target directory:
pushd "%~1" && (
rem // Clean up (pseudo-)array variable:
for /F "delims==" %%V in ('set "$FILES[" 2^> nul') do set "%%V="
rem /* Build list of matching files in array with random number as indices
rem plus a counter, just to avoid duplicate variable/element names: */
set /A "INDEX=0"
for /F "delims=" %%F in ('dir /S /B /A:-D-H-S "*.mov" "*.mp4"') do (
setlocal EnableDelayedExpansion & for %%R in (!RANDOM!_!INDEX!) do (
endlocal & set "$FILES[%%R]=%%F" & set /A "INDEX+=1"
)
)
rem /* Fetch the first three elements of the array of files, which becomes
rem implicitly sorted by the indices by the `set` command: */
set /A "INDEX=0"
for /F "tokens=1* delims=:=" %%E in ('set "$FILES[" 2^> nul') do (
setlocal EnableDelayedExpansion
if !INDEX! lss 3 endlocal & (
echo Selection: %%F
start "" "%%F"
) else endlocal
set /A "INDEX+=1"
)
rem // Return from target directory:
popd
)
endlocal
exit /B
There's a good chance that
findstr /l /v /C:"%%B" "%tempFile%" > "%tempFileTwo%"
may restore sanity.
If %%B contains spaces, then each individual word in "%%B" will be matched. The /c: instructs findstr to treat the quoted string as a string to match, not a list of substrings.
An easier way to achieve your objective would be:
In your main routine, before the pushd
:: remove variables starting $
FOR /F "delims==" %%b In ('set $ 2^>Nul') DO SET "%%b="
where $ can be any string you might desire, like #opened. This line clears any variable that starts $.
And in :openRandomFile, after setting randomNum,
if defined $%randomNum% goto openRandomFile
set $%randomNum%=Y
which establishes a flag $%randomnum% to prevent the number from being processed more than once.
I'm sure you can work out that adjusting the tempfiles can then be removed - including the decrement of cnt...

How to write a batch script to loop through logfiles in directory and generate a "filename.found" if i find the string "found" in the log file?

I have a directory "D:\logs" consisting of many log files eg: HRS.log, SRM.log, KRT.log, PSM.log etc.
Each of this log file may or may not have a string "found" inside them. If the log file contains the string "found", then i have to generate "fileName.found" eg: "SRM.found" file in "D:\flags"folder.
i have written the following script but not able to proceed further:
#echo off
setlocal ENABLEDELAYEDEXPANSION
for %%f IN ("D:\logs\*.log") do (
findstr /i "found" "%%f" >NUL
if "!ERRORLEVEL!"=="0" (
echo.>"D:\flags\%%f.found"
)
)
pause
exit /b
)
#echo off
for /f "delims=" %%A in (
'2^>nul findstr /i /m "found" D:\logs\*.log'
) do echo( > "D:\flags\%%~nA.found"
findstr /i can search in the files for the case insensitive string found and use of argument /m which allows for return of only the filepaths that contain that string. This can make it more efficient as the for /f command returns the filepaths only of interest.
%%~nA uses a for variable modifier of n which is the filename with no extension. View for /? for more information about the modifiers available.
ok, so here's the solution i found for the above question that i asked:
#echo off
setlocal enabledelayedexpansion
for %%f IN ("D:\logs\*.log") do (
find "found" "%%f" >NUL
if "!ERRORLEVEL!"=="0" (
echo.>"D:\flags\%%~nf.found"
)
)
pause
exit /b
)

Pull Partial File Name as Variable

I am looking for a short .bat script that can pull a partial file name and set it as a variable. The file names will consistently be the following structure, however there maybe more than 1 files at a time:
B06XTJ8RX3.MAIN.PC_430.jpg
or
B06XTJ8RX3.MRG1.PC_430.jpg
While there may be multiple files, the first 10 characters will be the same.
I want to name 'B06XTJ8RX3' as the variable. So far I have only been able to do this by writing the file names up to the first '.' into a text document and then pulling the contents of the text file removing the duplicate strings. All of that seems unnecessary.
set images=C:\file_path\images\
for /F "tokens=1 delims=." %%A IN ('dir /b %images%') do echo %%A >> dupes.txt
type NUL > asins.txt
for /F %%i in ('type dupes.txt ^| sort') Do (
If NOT "!prev!" == "%%i" (echo %%i>>asins.txt)
set prev=%%i
)
type NUL > dupes.txt
set prev=5000
Does anyone have a simple solution for this?
for /f "tokens=2delims==" %%x in (`set # 2^>nul`) do set "%%x="
set images=C:\file_path\images\
for /F "tokens=1 delims=." %%A IN ('dir /b %images%') do set /a "#%%A"+=1
set #
should report
#B06XTJ8RX3=2
for the above filenames (#firstelement=occurrences)
The for /f in the first line is intended to remove all variables starting # from the environment.
With each string detected, increment the count of #string found.
for /f "tokens=1,2delims==" %%x in (`set # 2^>nul`) do if "%%y" neq 1 echo %%x
should report each name with more than 1 file found.
If you guarantee that of the n files in the directory, the first 10 chars will all be the same and the 11th will be . (and therefore there are no files that do not fit this pattern) then
set images=C:\file_path\images\
set /a count=0
for /F "tokens=1 delims=." %%A IN ('dir /b /a-d %images%') do set "name=%%A"&set/a count+=1
echo the %count% files start "%name%"
use the /a-d switch to turn off directorynames, should they exist.
count them as a free bonus.

Extract section of a text file

I am trying to write a batch file that will extract lines 6000 to 6999 in a give text file. From googling I have come accross the following code - however this is giving me a blank output file.
#echo off
SetLocal EnableDelayedExpansion
type nul > nodedata.txt
set StartText=6000
set EndText=7000
set Flag=0
for /f "tokens=* delims=" %%a in ('type out.txt') do (
if /i "%StartText%" EQU "%%a" (set Flag=1)
if /i "%EndText%" EQU "%%a" (set Flag=0)
if !Flag! EQU 1 echo %%a >> nodedata1.txt
)
Any ideas as to where I am going wrong?
Here is a quick and simple pure batch solution
for /l %%a in (6000,1,6999) do (
more C:\file.txt +%%a >>C:\extracted.txt
)
You should install unxutils and then see answers for this question... Windows is just not made for text processing...
A Windows user...
This is a Batch solution that run faster...
#echo off
SetLocal EnableDelayedExpansion
set count=0
(for /F "skip=5999 delims=" %%a in (out.txt) do (
echo %%a
set /A count+=1
if !count! equ 1000 goto endLoop
)
) > nodedata1.txt
:endLoop

Using DOS batch script: find a line in a properties file and replace text

Trying to replace a string in a properties file on a certain line by using a batch file. I know that this can be done WITHOUT the use of a temp file, as I have seen it before, but forgotten how to do it.
I know that if I have a var.properties file that contains this:
CLASSPATH=bsh.jar;other.jar
VARTEST=dummy
ANOTHERVAR=default
I am trying to update the CLASSPATH value in the .properties file without changing the order of the properties file.
This is a properties file and so I believe the answer would be related to using:
for /f "tokens=1,2* delims==" %%i in (var.properties) do (
#echo Key=%%i Val=%%j
)
Instead of findstr use find with the /v and /i switches on "classpath". This will OMIT returning the line with classpath in it, then you can echo what you want in the file along w/VARTEST=dummy
SET NEWVAL=CLASSPATH=test.jar
SET FILE=think.properties
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%FILE%" ^|FIND /V /I "classpath"`) DO (
ECHO CLASSPATH=%NEWVAL%>>"%FILE%"
ECHO %%A>>"%FILE%"
)
EDIT:
SETLOCAL ENABLEDELAYEDEXPANSION
SET NEWVAL=test.jar
SET OLDFILE=OLD_think.properties
SET NEWFILE=think.properties
SET COUNT=1
MOVE "%NEWFILE%" "%OLDFILE%"
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%OLDFILE%" ^|FIND /C /I "classpath"`) DO (
SET LINE=%%A
)
FOR /F "USEBACKQ tokens=*" %%A IN (`FIND /V "" ^<"%OLDFILE%"`) DO (
IF %COUNT% NEQ %LINE% (ECHO %%A>>"%NEWFILE%") ELSE (ECHO %NEWVAL%>>"%NEWFILE%")
SET /a COUNT=!COUNT!+1
)
Basically states,
rename think.properties to OLD_think.properties
read OLD_think.properties and find the line number with string
"classpath" in it and set it to variable LINE
Find all lines in OLD_think.properties, and echo them into think.properties. once you reach the line where your "CLASSPATH" string existed, it inserts the new line you wanted to replace it with, and everything else stays the same.
I finally broke down and accepted a method using a "temp" file. Using delayed expansion with the '!' character solved my question. Much of this success was due to input by mecaflash .
You can call this script with: CALL Script.bat PropKey NewPropValue Filename
#echo off
:: script for updating property files
SETLOCAL EnableExtensions
SETLOCAL EnableDelayedExpansion
if "%3"=="" (
ECHO Script will optionally accept 3 args: PropKey PropVal File
SET PROPKEY=UseCompression
SET PROPVAL=false
SET FILE=config.properties
) ELSE (
SET PROPKEY=%1
SET PROPVAL=%2
SET FILE=%3
)
FINDSTR /B %PROPKEY% %FILE% >nul
IF %ERRORLEVEL% EQU 1 GOTO nowork
MOVE /Y "%FILE%" "%FILE%.bak"
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%FILE%.bak" ^|FIND /N /I "%PROPKEY%"`) DO (
SET LINE=%%A
)
FOR /F "tokens=1,2* delims=]" %%S in ("%LINE%") DO SET LINE=%%S
SET /A LINE=%LINE:~1,6%
SET /A COUNT=1
FOR /F "USEBACKQ tokens=*" %%A IN (`FIND /V "" ^<"%FILE%.bak"`) DO (
IF "!COUNT!" NEQ "%LINE%" (
ECHO %%A>>"%FILE%"
) ELSE (
ECHO %PROPKEY%=%PROPVAL%>>"%FILE%"
ECHO Updated %FILE% with value %PROPKEY%=%PROPVAL%
)
SET /A COUNT+=1
)
GOTO end
:nowork
echo Didn't find matching string %PROPKEY% in %FILE%. No work to do.
pause
:end

Resources