#ECHO OFF & SETLOCAL
copy /Y C:\LOG.DIR LOG.DIR
set "old=INACTIVE"
set "new=ACTIVE"
FOR /f %%a IN ('^<log.DIR find /v /c ""') DO SET /a length=%%a
SET /a length-=20
SETLOCAL ENABLEDELAYEDEXPANSION
<log.DIR (
FOR /l %%a IN (1,1,%length%) DO (
SET "line="
SET /p "line="
ECHO !line!
))>newfile
ENDLOCAL
for /f "skip=%length% delims=" %%a in (LOG.DIR) do (
set "str=%%a"
SETLOCAL ENABLEDELAYEDEXPANSION
set "str=!str:%old%=%new%!"
>>newfile ECHO !str!
endlocal
)
I just want to change last 20 lines from INACTIVE to ACTIVE. And if file has less than 20 lines, all lines of file should be changed.
But currently the new file is empty, if the number of lines in file is less than 20.
What to change to avoid an empty new file?
#echo off
setlocal enableextensions enabledelayedexpansion
copy /y c:\log.dir log.dir
set "old=INACTIVE"
set "new=ACTIVE"
for /f %%a in ('^<log.dir find /v /c ""') do set /a "length=%%a"
if %length% gtr 20 ( set /a "startPoint=length-20+1" ) else ( set "startPoint=1" )
<log.dir (
for /l %%a in (1,1,%length%) do (
set "line="
set /p "line="
if not defined line (
echo(
) else if %%a lss %startPoint% (
echo(!line!
) else (
echo(!line:%old%=%new%!
)
)
)>newfile
endlocal
Adjust where to start depending of the file length. If you have more than 20 lines, the starting point is calculated. If you have less lines, process from the start.
Related
I got a file containing a string on each line like this:
fruit-apple-1.5.6
vegtable-sla-mc5-6.5-16515
extra-huh-9.5-511-515
extra-3.2
I am iterating over it and want it to remove the part of the string on the right after in find "-" + any number "-0","-1","-2","-9",...
so output should be
fruit-apple
vegtable-sla-mc5
extra-huh
extra
this is code i have but it only works with a "-" i cant combine it so it takes "-" + any number like "-1","-5","-2",...
for /f "delims=|" %%A in ("!fileNameCheck:-=|!") do (
echo stripped string = %%A
)
complete code not necessary i think but in case u need it below
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set "RawPath=%~dp0"
FOR /F "USEBACKQ TOKENS=*" %%M IN ("%RawPath%/mods") DO (
REM for %%f in (*.jar) do (
Set "fileNameCheck=%%M"
for /f "delims=|" %%A in ("!fileNameCheck:-=|!") do (
Echo [46m%%A[0m
if exist "%~dp0%%A*.jar" (
REM echo [32mFound %%A "%~dp0%%A*.jar"[0m
if exist "%~dp0%%M" (
REM echo [42mUp to Date[0m [32m%%A "%~dp0%%M"[0m
) else (
for %%j in (*.jar) do (
echo %%j |find "%%A" >nul
if not errorlevel 1 (
echo [41mDifferent Version[0m [31m%%j [0m[90mNewer version[0m [32m%%M[0m
)
)
)
) else (
REM echo [31mMissing %%A[0m
)
)
)
pause
Given that the strings do not contain any of the caracters ?, *, < and >, the following script should do the trick:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=%~dp0."
set "_FILE=mods.txt"
rem // Read file line by line:
for /F usebackq^ delims^=^ eol^= %%L in ("%_FILE%") do (
rem // Store current line, initialise variables:
set "LINE=%%L" & set "PREV=-" & set "COLL=-"
setlocal EnableDelayedExpansion
rem /* Split line string at every `-` and iterate through items;
rem (`?`, `*`, `<`, `>` must not occur in the string!): */
for %%I in ("!LINE:-=" "!") do (
endlocal & set "ITEM=%%~I"
rem // Check whether item only consists of numerals and `.`:
(
rem // This loop executes when there are other characters:
for /F "delims=0123456789. eol=." %%J in ("%%~I") do (
setlocal EnableDelayedExpansion
rem /* Rebuilt string with currently found items; if there
rem are other items following numeric ones, keep them: */
for /F "delims=" %%K in ("!COLL!!PREV:~1!-!ITEM!") do (
endlocal & set "COLL=%%K" & set "PREV=-"
)
)
) || (
rem // This section runs when there are numerals and `.`:
setlocal EnableDelayedExpansion
for /F "delims=" %%K in ("!PREV!-!ITEM!") do (
rem /* Store numeric items in a separate buffer; if there
rem are no other items following, this is dismissed: */
endlocal & set "PREV=%%K"
)
)
setlocal EnableDelayedExpansion
)
rem // Return rebuilt line string:
echo(!COLL:~2!
endlocal
)
endlocal
exit /B
The example input file mods.txt:
fruit-apple-1.5.6
vegtable-sla-mc5-6.5
extra-huh-9.5
extra-3.2
test-9.15.5
keep-forge
name-subname-10.5-55.5
globalxp-1.16.5
mix-1.2-string-10.5-55.5-more
mix-1.2-string-10.5-55.5-more-3.4
mix-1.2-string-10.5-55.5-more-3.4-5.6-7
8.9
1.2.3-lead
1.2.3-4.5.6-7.8.9-lead-mult
leads to the following output:
fruit-apple
vegtable-sla-mc5
extra-huh
extra
test
keep-forge
name-subname
globalxp
mix-1.2-string-10.5-55.5-more
mix-1.2-string-10.5-55.5-more
mix-1.2-string-10.5-55.5-more
1.2.3-lead
1.2.3-4.5.6-7.8.9-lead-mult
One way is to replace the - with \ and then use variable substitution to strip the %%~ni part from the string. We just need to remove the first and last occurrence then from the string. findstr will determine that the end of string needs to be -num.*
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%A in ('dir /b /s *.jar ^| findstr /RC:"-[0-9].*$"') do (
set "line=%%~nxA"
for %%i in ("!line:-=\!") do set "final=%%~pi"
set "final=!final:~0,-1!-"
echo !final! | findstr /RC:"\\[0-9].*$" >nul 2>&1
if !errorlevel! equ 0 (
for %%s in ("!final!") do set "final=%%~ps"
set final=!final!
)
set "final=!final:~0,-1!"
set "final=!final:~1!"
echo !final:\=-!
)
the edited code should take care of the additional - as per your comment example name-subname-10.5-55.5
Here's an untested idea, which may not be particularly quick, especially if you have a large number of strings in your mods file:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F %%G In ('Echo Prompt $E ^| %SystemRoot%\System32\cmd.exe /D'
) Do Set "$E=%%G"
For /F Delims^=^ EOL^=^ UseBackQ %%G In ("%~dp0mods") Do (Set "Line=%%G"
SetLocal EnableDelayedExpansion
For /L %%H In (0 1 9) Do For /F Delims^=^ EOL^= %%I In (
'(Echo(^) ^| Set /P "=!Line:-%%H="^&:"!" 0^<NUL') Do Set "Line=%%I"
Echo(%$E%[46m!Line!%$E%[0m
EndLocal
)
Pause
Here i am printing line no 1 to 5 from a file to another file.its working fine but one small issue that the lines are trimming from left side,i do not want to trim,it should be same as the input file.
infile.txt:
<RCO-XXX-AGENT>
<CREATED>2018-06-28 10:19:09</CREATED>
<FORMAT>
<VARIABLE>
<EOR>/010</EOR>
<EOC>/009</EOC>
<CTR>5</CTR>
code:
echo off
setlocal enabledelayedexpansion
call :Print_Lines > outfile.txt
endlocal
:Print_Lines
setlocal enabledelayedexpansion
set cur=0
for /f "delims==" %%i in (infile.txt) do (
set /a cur=cur+1
if !cur! geq 1 (
if !cur! leq 5 (
for /f "tokens=*" %%j in ( "%%i") do (
echo %%j
)
)
)
)
endlocal
exit /b 0
goto :eof
outfile.txt:
<RCO-XXX-AGENT>
<CREATED>2018-06-28 10:19:09</CREATED>
<FORMAT>
<VARIABLE>
<EOR>/010</EOR>
The second loop is useless
It should work :
echo off
setlocal enabledelayedexpansion
call :Print_Lines > outfile.txt
endlocal
:Print_Lines
setlocal enabledelayedexpansion
set cur=0
for /f "delims==" %%i in (infile.txt) do (
set /a cur=cur+1
if !cur! geq 1 (
if !cur! leq 5 (
echo %%i
)
)
)
endlocal
exit /b 0
goto :eof
In your exemple, the spaces at left are not printed because they are considered as delimiter character
I would suggest this method:
#Echo Off
Set "Num=5"
<"infile.txt" (For /L %%A In (1,1,%Num%) Do (Set "_="
Set /P "_="
SetLocal EnableDelayedExpansion
Echo=!_!
EndLocal))>"outfile.txt"
Where you can adjust the value to Num as necessary.
Suppose I have a text file like this
node1.log
node2.log
node3.log
node4.log etc...
I want to read each line by line and execute
alan.exe node1.log node2.log
alan.exe node3.log node4.log
etc..
What is the best way to accomplish this?
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in (file.txt) do (
if not defined line (
set "line=%%a"
) else (
ECHO alan.exe !line! %%a
set "line="
)
)
Give this a try. File.txt will have your log file names.
#echo off
setlocal enabledelayedexpansion
FOR /F "delims=" %%G IN ('find /c /v "" ^<file.txt') DO SET NUM=%%G
SET /A NUM=NUM / 2
< file.txt (
FOR /L %%G IN (1,1,%NUM%) DO (
SET /P LINE1=
SET /P LINE2=
echo mypgm.exe !LINE1! !LINE2!
)
)
pause
Output
mypgm.exe node1.log node2.log
mypgm.exe node3.log node4.log
mypgm.exe node5.log node6.log
Press any key to continue . . .
Remove the word echo and replace mypgm.exe with the program you want to run. The echo is just in there for the proof of concept.
Like this:
#echo off
setlocal enabledelayedexpansion
set args=
set n=2
for /f "tokens=*" %%x in (file.txt) do (
set args=!args! %%x
set /a n -= 1
if !n! EQU 0 (
alan !args!
set args=
set n=2
)
)
Good Afternoon!
Long time reader, first time poster! I have been having a lovely time trying to modify a working batch file to account for variability. The situation is that I have a variable-size text document that normally would be able to be split into sections of 252 lines. The code below worked like a champ:
#echo off & setlocal EnableDelayedExpansion
set param=%*
if not defined param (
echo.
echo. Usage: batchsplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
goto :EOF
)
for %%j in ("%param%") do (
set name=%%~dpnj
set ext=%%~xj
)
for /F %%j in ('type "%param%" ^| find /V /C ""') do set Full=%%j
set /A Split=%Full%/252
for /L %%G in (1,1,%Split%) do type nul > "%name%_%%G%.new"
set X=1
set N=1
set Q=1
set limit = 252
for /F "tokens=1* delims=]" %%j in ('type "%param%" ^| find /V /N ""') do (
set /A N+=1
set /A Q+=1
echo.%%k>> "%name%_!X!%.new"
if !Q! gtr 252 (
set /A X+=1
set /A Q=1
) else if !N! gtr Full (goto theend
)
)
:theend
echo split into %split% files with 252 lines each
rem pause
However, there were some changes to the formatting of the text, and now instead of four pages of 63 lines per split file, it can be completely variable. The only constant is this final line, which precedes the remaining space for a 63 line page:
ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
Note that there is a single space in front of it, as well as multiple spaces, a colon, and underscore characters. Being the meathead that I am, I thought I could insert an if-then statement into the for loop to trigger the batch to split to the next page. However, I could be further from that right now. This is the code I have been smashing my head with:
rem #echo off & setlocal EnableDelayedExpansion
setlocal EnableDelayedExpansion
set param=%*
if not defined param (
echo.
echo. Usage: textsplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
goto :EOF
)
for %%j in ("%param%") do (
set Name=%%~dpnj
set ext=%%~xj
)
for /F %%j in ('type "%param%" ^| find /V /C ""') do set Full=%%j
set stopvar= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
set Split=1
echo %stopvar%
set X=1
type nul > "%name%_!X!%.new"
set N=1
set Q=1
set S=0
set L=63
for /F "tokens=1* delims=]" %%j in ('type "%param%" ^| find /V /N ""') do (
set /A N+=1
echo %N%
set /A Q+=1
echo %Q%
echo.%%k>> "%name%_!X!%.new"
if ["%%k%" == "!stopvar!"] (
set /A S+=1
)
if !Q! gtr !L! (
if !S! == 1 (
set /A X+=1
set /A Q=1
type nul > "%name%_!X!%.new"
set /A Split+=1
set S=0
)
else set /A L+=63
else if !N! gtr Full goto theend
)
:theend
echo Split into %split% files!
pause
The premise is that every 63 lines, the stop variable (S) is checked. If it is off (0) then the batch will continue to write for another 63 lines (one page). If the stopvar matches the line that is being read by the for loop, S becomes 1. When the program checks again, it will create a new file and begin writing to that new file. Right now, based on turning off #echo off the hangup is at the for loop. See below:
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>rrtextsplit texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>rem #echo off & setlocal Enabl
eDelayedExpansion
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>setlocal EnableDelayedExpansio
n
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set param=texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>if not defined param (
echo.
echo. Usage: rrtextsplit [device:][pathname]filename
goto :EOF
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set param=texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>if not exist "texttest.txt" (
echo.
echo. File "texttest.txt" not found
goto :EOF
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>for %j in ("texttest.txt") do
(
set Name=%~dpnj
set ext=%~xj
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>(
set Name=C:\Users\theangryasiancp\Desktop\TEXT_Split_Test\texttest
set ext=.txt
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>for /F %j in ('type "texttest.
txt" | find /V /C ""') do set Full=%j
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Full=567
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set stopvar= ON THIS FORM IS C
OMPLETE AND CORRECT AS NOTED:___________________
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Split=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>echo ON THIS FORM IS COMPLETE
AND CORRECT AS NOTED:___________________
ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set X=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>type nul 1>"C:\Users\theangry
asiancp\Desktop\RRRR_Split_Test\texttest_!X!.new"
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set N=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Q=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set S=0
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set L=63
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>
What are your thoughts? Where am I going wrong with the batch? I wish I could use something different, but alas I cannot, for internal company reasons. Thanks for your help!
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "name=q23396663"
SET "ext=.txt"
SET /a pagelength=10
SET "targetstring= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________"
SET /a filenum=0
SET /a linecount=pagelength + 1
FOR /f "tokens=1*delims=]" %%a IN (
'find /v /n "" "%name%%ext%"') DO (
IF !linecount! GEQ %pagelength% (
SET /a linecount=0
SET /a filenum+=1
)
>>U:\%name%_!filenum!.new ECHO(%%b
IF "%%b"=="%targetstring%" SET /a linecount=pagelength
SET /a linecount+=1
)
GOTO :EOF
For testing purposes, I set up a file q23396663.txt containing your trigger data. I've left the destination directory as U:\ which suits me, and the pagelength at 10 which makes my testing easier.
#echo off
setlocal EnableDelayedExpansion
REM ------------------THIS SECTION SPECIFIES THE FILE-------------------------
set param=%*
if not defined param (
echo.
echo. Usage: filesplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
GOTO :EOF
)
for %%j in ("%param%") do (
set name=%%~dpnj
set ext=%%~xj
)
ECHO SPLITTING %name%.%ext% .................
REM ----------------THIS SECTION SETS THE VARIABLES---------------------------
set "trigger= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________"
set /a pagelength=63
set /a filenum=0
set split=1
set /a linecount=pagelength
set stopvar=0
REM ------------------THIS SECTION IS THE FOR LOOP----------------------------
FOR /f "skip=2 tokens=1* delims=]" %%a IN (
'find /v /n "" "%name%%ext%"') DO (
SET /a linecount-=1
IF !linecount! LEQ 0 (
IF !stopvar! EQU 1 (
SET /a "linecount=pagelength"
SET /a filenum+=1
SET /a split+=1
SET /a stopvar-=1
) else set /a "linecount=pagelength"
)
echo.%%b>> "%name%_!filenum!.new"
IF "%%b"=="%trigger%" (
set /a "stopvar+=1"
REM THIS TRIGGERS TO CHANGE OUTPUT
set /a linecount+=1
REM THIS WILL ADJUST THE OUTPUT EOF
)
)
REM ----------------THIS SECTION ENDS THE FOR LOOP----------------------------
ECHO Split into %split% files!
ping 1.1.1.1 -n 1 -w 2500 > nul
REM THIS PAUSES THE BATCH FOR A SEC
As I posted in the comment above, this is just a variation of the first answer that accounts for blank spaces if they are needed to keep the output files from having unnecessary whitespace on top. This is especially helpful when a print manager is just spitting out whitespace until the end of the page before starting the next part instead of going straight to the next portion.
I need to get file name with out the file extension, folder name out putted to a csv file. I am able to get file name and folder name using:
#ECHO OFF
SETLOCAL
PUSHD "%~1"
FOR /f "delims=" %%i IN ("%cd%") DO SET directory=%%~nxi
(
FOR /f "delims=" %%i IN ('dir /b /a-d /on') DO (
SETLOCAL enabledelayedexpansion
ECHO "%%i","!directory!"
endlocal
)
)>filelist.csv
How can I rewrite this so the file extension is removed and if there are subfolders it will grab the subfolder name too?
#echo off
setlocal enableextensions disabledelayedexpansion
if not "%~1"=="" (
(for /f "tokens=*" %%i in ('dir /s /b /on "%~1\*"') do (
set "file=%%~dpni"
setlocal enabledelayedexpansion
echo(!file:%~dp1=!
endlocal
)) > filelist.csv
) else (
call "%~f0" "%cd%"
)
endlocal
Not sure about the final format. Try and comment.
EDITED - to handle case exposed by Andriy M
#echo off
setLocal
pushd "%~1"
set "cur_path=%cd:~2%"
setLocal enableDelayedExpansion
FOR /f "delims=" %%i IN ('dir /b /s /a-d /on') DO (
SET "file_path=%%~dpni"
SET "file_path=!file_path:~2!"
SET "file_path=!file_path:%cur_path%=!"
ECHO "!file_path!","%%~di%cur_path%"
)
endLocal
endLocal
EDIT
with additional ~ replacing (comparatively slow - could be optimized with macros... ):
#echo off
pushd .
set "cur_path=%cd:~2%"
call :wavereplacer "%cur_path%" "-" nw_cur_path
setlocal enableDelayedExpansion
FOR /f "delims=" %%i IN ('dir /b /s /a-d /on') DO (
SET "file_path=%%~dpni"
SET "file_path=!file_path:~2!"
SET "file_path=!file_path:%cur_path%=!"
CALL :wavereplacer "!file_path!" "-" file_path
ECHO "!file_path!","%%~di%nw_cur_path%"
)
endlocal
endlocal
goto :eof
:wavereplacer String Replacer [RtnVar]
setlocal
rem the result of the operation will be stored here
set "result=#%~1#"
set "replacer=%~2"
call :strlen0.3 result wl
call :strlen0.3 replacer rl
:start
set "part1="
set "part2="
rem splitting the string on two parts
for /f "tokens=1* delims=~" %%w in ("%result%") do (
set "part1=%%w"
set "part2=%%x"
)
rem calculating the count replace strings we should use
call :strlen0.3 part1 p1l
call :strlen0.3 part2 p2l
set /a iteration_end=wl-p1l-p2l
rem creating a sequence with replaced strings
setlocal enableDelayedExpansion
set "sequence="
for /l %%i in (1,1,%iteration_end%) do (
set sequence=!sequence!%replacer%
)
endlocal & set "sequence=%sequence%"
rem adjust the string length
set /a wl=wl+iteration_end*(rl-1)
rem replacing for the current iteration
set result=%part1%%sequence%%part2%
rem if the second part is empty the task is over
if "%part2%" equ "" (
set result=%result:~1,-1%
goto :endloop
)
goto :start
:endloop
endlocal & if "%~3" neq "" (set %~3=%result%) else echo %result%
exit /b
:strlen0.3 StrVar [RtnVar]
setlocal EnableDelayedExpansion
set "s=#!%~1!"
set "len=0"
for %%A in (2187 729 243 81 27 9 3 1) do (
set /A mod=2*%%A
for %%Z in (!mod!) do (
if "!s:~%%Z,1!" neq "" (
set /a "len+=%%Z"
set "s=!s:~%%Z!"
) else (
if "!s:~%%A,1!" neq "" (
set /a "len+=%%A"
set "s=!s:~%%A!"
)
)
)
)
endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b