CMD Batch and 7z : Capture the progress of the extraction - batch-file

I'm trying to extract something using the 7zip command line tool from a batch file
and i want just the percentage progress to appear
my code is
#echo off
for /f "tokens=3 delims=. " %%i in (
'7z x "file.rar" ^| findstr /b /r " [0-9][0-9]*\%%"'
) do (
cls
echo %%i
)
PAUSE
but all i get out is just blank during the whole extracting progress .
what went wrong?

The problem is that a FOR /F take the whole output of a command and when the command is finished it begins to iterate over the lines.
Well, this can't be used to solve your task.
But you can pipe the output to another process, in this sample I use the same batch as the second process ( %~f0 is the batch itself )
#echo off
setlocal EnableDelayedExpansion
if "%~1"==":pipe" goto %~1
7z x "file.rar" | findstr /b /r " [0-9][0-9]*\%%" | "%~f0" :pipe
echo Ready
exit /b
:pipe
set "line="
set /p line=
if defined line (
echo #### !line!
goto :pipe
)

Related

Log contents of text file before deleting

My script isn't logging the contents of run.txt to log.txt
I've tried to remove the delete command to see if it was deleting it too quickly and therefore couldn't log. But that wasn't the case.
What should I change?
#ECHO OFF &setlocal
SET File=run.txt
type %File%
for /f "tokens=*" %%A in (%File%) do (echo >> log.txt)
del "%File%" /s /f /q > nul
pause
Here is a very simple way to do the task you are requiring.
#echo off
REM Will only grab the first line of the file
set /p file=<run.txt
REM For the last line use a for loop
for /f "tokens=*" %%a in (%file%) do set last_line=%%a
(
echo %file%
)>>log.txt
del /f %file% >nul
If not %errorlevel% equ 0 (
ECHO ERROR - %errorlevel%
pause
exit /b
)
ECHO Success!
timeout /t 003
exit /b %errorlevel%
EXPLANATION
set /p is for set prompt. For more information you can use set /? in your CMD window or check out this site.
I wish I could speak more on what < does, but what it is doing here is piping the content of run.txt to our variable.
Then we echo out our variable to our log file with (ECHO This is our %file%)>>destination
>> is to append where > is to overwrite the file.
(
echo %file%
echo.
)>>%file%
Checking for an error is probably unnecessary, but I believe it is a good habit to build on which is what I am trying to do with that If not %errorlevel% statement.
No error? We Success and timeout ourselves for xxx seconds.
Try:
#ECHO OFF &setlocal
SET "File=run.txt"
type "%File%" >> "log.txt" && (del "%File%" /f > nul)
pause

Batch .txt reader

So, basically I want a Batch file to read a .txt. The problem is that the Batch file needs to update everytime a new line gets written to the .txt
#echo off
set "pc=%1"
FOR /F "delims=:" %%A IN ('findstr /N .* "%pc%"') DO set "zeilen=%%A"
type %pc%
set /A zeilen1=%zeilen%
:loop
if not %zeilen% == %zeilen1% (
set "line="
set zeilen2=%zeilen% - 1
for /f %%a in ('more/e +%zeilen2% ^< %pc%') do (
if not defined line set "line=%%a"
)
echo %line%
set /A zeilen+=1
)
FOR /F "delims=:" %%A IN ('findstr /N .* "%pc%"') DO set "zeilen1=%%A
goto loop
I also can't use the type command (line 9-13) because I don't want to refresh the whole .txt only the last line.
sry for my poor english
Thanks
To start the Batch you need to do something like this call batch.cmd txtname.txt
A basic tail command can be written like so. Credit to #dbenham for his initial solution on DosTips.com
#echo off
call :Loop <"tailme.txt"
exit
:Loop
set "line="
set /p "line="
if defined line (
echo %line%
) else (
pathping -q 1 -p 300 localhost >nul
)
goto :loop
If you don't wish to use third party options and wish to keep it pure batch, it is very possible. From your question, it sounds like you wish to read the last line of a text file and have it update that text each time the text file is edited. Further more, this batch file much be call'ed to when it needs to be used.
To do this, we can compare the date it was last modified using forfiles in an for loop. The reason for this is that if we use the file properties EX: ECHO Last-Modified Date : %%~ta we will not get the properties down to seconds. Thus the file will only compare down to the minutes.
Now that we can grab the last modified properties we can use an IF statement to look for when the file get a new time stamp. From there we can use a modified script that reads only the last line of a text file (Configurable by set /a LINES=LINES+1 LINES+1 - Infin) made by #Patrick Cuff
To call this batch file you will want to use call ReadFile.bat txtname.txt
Call - Command
ReadFile.bat - Name of batch script
txtname.txt - Name of textfile to read
Bellow is the full script.
ReadFile.bat
#ECHO OFF
#GOTO READ
:LOOP
Rem | Look for changes
FOR /f %%a in ('forfiles /M %1 /C "cmd /c echo #fdate-#ftime"') DO (set FileTimeCurrent=%%a)
IF "%FileTimeLoad%"=="%FileTimeCurrent%" (goto LOOP) else (goto READ)
:READ
cls
Rem | Get current date
FOR /f %%a in ('forfiles /M %1 /C "cmd /c echo #fdate-#ftime"') DO (set FileTimeLoad=%%a)
Rem | Get the number of lines in the file
set LINES=0
for /f "delims==" %%I in (%1) do (
set /a LINES=LINES+1
)
Rem | Print the last line
set /a LINES=LINES-1
more +%LINES% < %1
goto LOOP
For help on any of the commands do the following:
call /?
set /?
for /?
if /?
So on.

Supress all output in this batch file

I have the following batch file which outputs limited info. How do I suppress all output from this batch file? What I'd like to see is after I enter the name of the batch file and hit enter, the next thing that shows up on screen is "C:>".
#ECHO OFF
SETLOCAL EnableDelayedExpansion
(for /f "tokens=1 delims=;" %%A in (C:\ALL.txt) do (
#echo %%A | find /i "\"
if errorlevel 1 (
DEL "D:\!mypath!%%A" >> C:\ALL-OUT.txt 2>&1
) ELSE (
set mypath=%%A
)))
#endlocal
I think it all boils down to this line which I use to test whether %%A contains backslash:
#echo %%A | find /i "\"
I tried adding " 1>null" to the end of the line. It worked to suppress all output. However, it also created a file named "null".
Since "For /f" parses files line by line, I wonder if there is a way to incorporate the echo command in "For /f"?
The NUL device is referenced with nul, not null. >null creates a file named null.
for your second question: you can redirect the output of a command block with a single redirection (in fact, this is way faster)
#ECHO OFF
SETLOCAL EnableDelayedExpansion
(
for /f "delims=;" %%A in (C:\ALL.txt) do (
echo %%A | find "\" >nul
if errorlevel 1 (
DEL "D:\!mypath!%%A"
) ELSE (
set mypath=%%A
)
)
) > C:\ALL-OUT.txt 2>&1
endlocal

Replace line in config file with batch afterward start exe

With a batch file, I want to change a value in a configuration file:
"title.connectionString" : "ServerIP",
ServerIP is the variable to be changed. So the batch file has to give people who use it an option to choose from 4 prefixed IPs. After they selected one of the 4 the IP, the config file has to be saved with new value and the batch file should run an executable.
Has anyone got an idea how I can do this with a batch file?
Easy, try this code:
#echo off
:start
Echo Select Ip:
Echo.
Echo 1. 10.0.0.0
Echo 2. 10.0.0.1
Echo 3. 10.0.0.2
Echo 4. 10.0.0.1
Echo.
Choice /c 1234 /m "Ip: " /n
set choice=%errorlevel%
set ip=
if %choice%==1 set ip=10.0.0.0
if %choice%==2 set ip=10.0.0.1
if %choice%==3 set ip=10.0.0.2
if %choice%==4 set ip=10.0.0.3
if "%ip%"=="" (Echo Error, null variable & goto :start)
ren config.txt config.tmp
setlocal Enabledelayedexpansion
for /f "tokens=*" %%a in (config.tmp) do (
set line=%%a
Echo !line:ServerIP=%ip%! >> config.txt
)
del config.tmp
And that should do what you want.
Mona
#echo off
setlocal enableextensions
call :replaceKeyValue "file.config" "title.connectionString" "123456789"
endlocal
exit /b
:replaceKeyValue file key value
setlocal enableextensions disabledelayedexpansion
ren "%~f1" "%~nx1.tmp" >nul && (
(for /f tokens^=1^,*^ delims^=^:^ eol^= %%k in ('findstr /n "^" ^<"%~f1.tmp"') do (
echo(%%l|findstr /c:"\"%~2\"" >nul && (
for /f "tokens=1 delims=:" %%v in ("%%l") do echo(%%~v : "%~3",
) || (
echo(%%l
)
)) > "%~f1"
del "%~f1.tmp" > nul
)
endlocal
This will handle the replacement of the value in the file. Monacraft answer shows a perfect way of selecting the required ip.
This will rename the file to file.tmp and for each line in the file (findstr /n is used to avoid lost of empty lines) it is tested agains the passed key. When required line is found, it is split using the colon (to keep the indentation) and value replaced with supplied value. All the non matching lines are echoed as is. All the output of the process is send to the original file and at end, the .tmp file is deleted.

Deleting last n lines from file using batch file

How to delete last n lines from file using batch script
I don't have any idea about batch files, I am writing batch file for the first time.
How should I write this batch file?
For Windows7
Try it for
<Project_Name>
<Noter>
<Common>
<File>D:\Project_Name\Util.jar</File>
<File>D:\Project_Name\Noter.bat</File>
<File>D:Project_Name\Noter.xml</File>
<File>D:Project_Name\Noter.jar</File>
</Common>
<Project_Name>
<File>D:\Util.bat</File>
<File>D:\Util.xml</File>
<File>D:\log.bat</File>
</Project_Name>
</Noter>
<CCNET>
This the complete script for remove last N line
count the total line
set Line = Line - N , remain just processing lines number
#echo OFF
setlocal EnableDelayedExpansion
set LINES=0
for /f "delims==" %%I in (infile.txt) do (
set /a LINES=LINES+1
)
echo Total Lines : %LINES%
echo.
:: n = 5 , last 5 line will ignore
set /a LINES=LINES-5
call:PrintFirstNLine > output.txt
goto EOF
:PrintFirstNLine
set cur=0
for /f "delims==" %%I in (infile.txt) do (
echo %%I
::echo !cur! : %%I
set /a cur=cur+1
if "!cur!"=="%LINES%" goto EOF
)
:EOF
exit /b
Here call:PrintFirstNLine > output.txt will give the output in an external file name as output.txt
Output for sample Input
<Project_Name>
<CBA_Notifier>
<Common>
<File>D:\CBA\CBA_Notifier\Project_Name\IPS-Util.jar</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.bat</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.xml</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.jar</File>
</Common>
<Project_Name>
<File>D:\CBA\CBA_Notifier\IPS-Util.bat</File>
remove last 5 line
Update
:PrintFirstNLine
set cur=0
for /F "tokens=1* delims=]" %%I in ('type "infile.txt" ^| find /V /N ""') do (
if "%%J"=="" (echo.) else (
echo.%%J
set /a cur=cur+1
)
if "!cur!"=="%LINES%" goto EOF
)
This script will takes 1 arguement, the file to be trunkated, creates a temporary file and then replaces the original file with the shorter one.
#echo off
setlocal enabledelayedexpansion
set count=
for /f %%x in ('type %1 ^| find /c /v ""') do set /a lines=%%x-5
copy /y nul %tmp%\tmp.zzz > nul
for /f "tokens=*" %%x in ('type %1 ^| find /v ""') do (
set /a count=count+1
if !count! leq %lines% echo %%x>>%tmp%\tmp.zzz
)
move /y %tmp%\tmp.zzz %1 > nul
If the original file is 5 or less lines, the main output routine will noT create a file. To combat this, I use the copy /y null to create a zero byte file.
If you would rather not have an empty file, just remove the copy /y nul line, and replace it with the following line:
if %lines% leq 0 del %1
You should use one method or the other, otherwise source files with 5 or less lines will remain untouched. (Neither replaced or deleted.)
to delete last lines from your file,
1 copy starting lines that are needed from file like from- e:\original.txt
2 paste them in new file like- e:\new\newfile1.txt
code is thanks to the person giving me this code:
remember all may be done if you have motive and even blood hb =6. but help of nature is required always as you are a part of it
#echo off & setLocal enableDELAYedeXpansion
set N=
for /f "tokens=* delims= " %%a in (e:\4.txt) do (
set /a N+=1
if !N! gtr 264 goto :did
e:\new4.txt echo.%%a
)
:did
if you have 800 files then use excel to make code for 800 and then copy it to notepad and using Ctrl+h replace space with no space. then rename file as haha.bat . run in folder with files numbered 1.txt 2.txt 3.txt etc. any enquirers welcome Erkamaldev#gmail.com " Long Live Bharata"
A slow method with less coding:
set input=file.txt
set remove=7
for /f "delims=" %i in ('find /c /v "" ^< "%cd%\%input%"') do set lines=%i
set /a lines-=remove
for /l %i in (1,1,!lines!) do findstr /n . log.txt | findstr /b %i:
May be redirected to a file.
Each line is prefixed with the line number; may be removed with extra coding.
A faster version with /g flag in my answer at:
How to split large text file in windows?
Tested in Win 10 CMD, on 577KB file, 7669 lines.

Resources