56675 Dec 27 2003 ftp://garbo.uwasa.fi/pc/link/tscmd.zip
tscmd.zip Useful NT/2000/XP script tricks and tips, T.Salmi
I note, with particular compliments to Al Dunbar and Phil Robyn,
that the SET /P techniques they have come up with and demonstrated
can well be fitted as one of the options for also these tasks.
Tested in Windows XP [Version 5.1.2600]
------------------------------------------------------------------------
(snip: The subroutine examples already there)
There are other options like
@echo off & setlocal enableextensions
:: Make a test file
for %%f in (mytest.txt mytemp.txt) do if exist %%f del %%f
for %%f in (1 2 3 4 5 6 7 8 9) do echo This is line %%f>>mytest.txt
::
:: Special get the first line of a file
set /p line_=<mytest.txt
echo %line_%
::
:: Special get the last file of a file
for /f "delims=" %%r in ('type mytest.txt') do set line_=%%r
echo %line_%
::
:: Special get the Nth line
set /a n_=5-1
for /f "skip=%n_% delims=" %%r in ('type mytest.txt') do echo %%r>>mytemp.txt
set /p line_=<mytemp.txt
echo %line_%
::
:: Clean up
for %%f in (mytest.txt mytemp.txt) do if exist %%f del %%f
endlocal & goto :EOF
The output is
D:\TEST>cmdfaq
This is line 1
This is line 9
This is line 5
(snip: A few new words on the alternative SED and GAWK batch
solution pointers to these same tasks.)
------------------------------------------------------------------------
All the best, Timo
--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
Timo's FAQ materials at http://www.uwasa.fi/~ts/http/tsfaq.html
> Revisiting that item from
>
> 56675 Dec 27 2003 ftp://garbo.uwasa.fi/pc/link/tscmd.zip
> tscmd.zip Useful NT/2000/XP script tricks and tips, T.Salmi
>
> I note, with particular compliments to Al Dunbar and Phil Robyn,
> that the SET /P techniques they have come up with and demonstrated
> can well be fitted as one of the options for also these tasks.
> Tested in Windows XP [Version 5.1.2600]
>
> ------------------------------------------------------------------------
<<<<snip>>>>
> ::
> :: Special get the last file of a file
> for /f "delims=" %%r in ('type mytest.txt') do set line_=%%r
> echo %line_%
The preceding will be *extremely* slow if the file is large. Here's a
much faster way to get the last line of a large file:
- - - - - - - - - - begin screen capture - - - - - - - - - -
<Win2000> c:\cmd>rlist demo\TestGetLastLine1.cmd
=====begin c:\cmd\demo\TestGetLastLine1.cmd ====================
1. @echo off
2. for /f %%a in ('find /v /c "" ^< %1') do set /a linecount=%%a
3. set /a linecount-=1
4. for /f "tokens=*" %%a in ('more /e +%linecount% %1') do set last_line=%%a
=====end c:\cmd\demo\TestGetLastLine1.cmd ====================
<Win2000> c:\cmd>dir d:\junkdir\glemail.log | find "/"
08/04/01 04:57p 1,810,937 glemail.log
<Win2000> c:\cmd>reccount d:\junkdir\glemail.log .
File d:\junkdir\glemail.log has 16949 records.
<Win2000> c:\cmd>echo %time% & demo\TestGetLastLine1 d:\junkdir\glemail.log & echo !time!
1:45:43.05
1:45:43.93
<Win2000> c:\cmd>set last_line
last_line=2001/08/04 15:01:13.30 GLEMAIL5 ************************ ENDED *****************************
- - - - - - - - - - end screen capture - - - - - - - - - -
--
Phil Robyn
Univ. of California, Berkeley
u n z i p m y a d d r e s s t o s e n d e - m a i l
Thanks Phil. I suspected as much.
> =====begin c:\cmd\demo\TestGetLastLine1.cmd ====================
> 1. @echo off
> 2. for /f %%a in ('find /v /c "" ^< %1') do set /a linecount=%%a
> 3. set /a linecount-=1
> 4. for /f "tokens=*" %%a in ('more /e +%linecount% %1') do set last_line=%%a
Included suitably edited to fit with the rest of the item, naturally
with the acknowledgement.
I wonder if that somehow could be utilized to also have a faster way
to get the N:th line.
All the best, Timo
--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
Useful script files and tricks ftp://garbo.uwasa.fi/pc/link/tscmd.zip
In one of my recent postings I used:
>nul for /f "tokens=1 delims=:" %%a in ('findstr /n "\<*" "%1"') do set n=%%a
Do you think your method is faster?
?
try this one:
@echo off
echo %time%>test_time.txt
for /f "tokens=1 delims=:" %%a in ('findstr /n "\<*" "%1"') do set n=%%a
echo %n%
echo %time%>>test_time.txt
for /f %%a in ('find /v /c "" ^<%1') do set linecount=%%a
echo %linecount%
echo %time%>>test_time.txt
That line count version gives me the idea for yet one formulation
for getting the Nth line:
@echo off & setlocal enableextensions enabledelayedexpansion
:: Make a test file
for %%f in (mytest.txt mytemp.txt) do if exist %%f del %%f
for %%f in (1 2 3 4 5 6 7 8 9) do echo This is: line %%f>>mytest.txt
::
set /a GetLineNumber=5
for /f "tokens=1,* delims=:" %%a in ('findstr /n "\<*" "mytest.txt"') do (
set /a LineCount_=%%a
if !LineCount_! EQU %GetLineNumber% set line_=%%b)
echo %line_%
::
:: Clean up
for %%f in (mytest.txt mytemp.txt) do if exist %%f del %%f
endlocal & goto :EOF
The output will be
D:\TEST>cmdfaq
This is: line 5
All the best, Timo
--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
In a single test the latter was marginally faster for a file with a
1000 lines.
All the best, Timo
--
Prof. Timo Salmi ftp & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/> ; FIN-65101, Finland
Hi, Timo and Uno:
Following is a comparison of the three methods on a file of moderate size.
The first two methods are roughly equivalent; the third is significantly
faster. I would hate to try either of the first two methods on large files.
- - - - - - - - - - begin screen capture - - - - - - - - - -
<Win2000> c:\cmd>dir d:\banway\2003-12-31.log | find "/"
01/01/04 02:02a 174,878 2003-12-31.log
<Win2000> c:\cmd>reccount d:\banway\2003-12-31.log .
File d:\banway\2003-12-31.log has 2981 records.
<Win2000> c:\cmd>rlist demo\TestGetLastLine3.cmd
=====begin c:\cmd\demo\TestGetLastLine3.cmd ====================
1. @echo off
2. echo %time%
3. for /f "tokens=1 delims=:" %%a in ('findstr /n "\<*" "%1"') do set n=%%a
4. echo %time%
=====end c:\cmd\demo\TestGetLastLine3.cmd ====================
<Win2000> c:\cmd>demo\TestGetLastLine3 d:\banway\2003-12-31.log
8:38:49.72
8:38:53.33
<Win2000> c:\cmd>rlist demo\TestGetLastLine2.cmd
=====begin c:\cmd\demo\TestGetLastLine2.cmd ====================
1. @echo off
2. echo %time%
3. for /f "delims=" %%a in ('type %1') do set last_line=%%a
4. echo %time%
=====end c:\cmd\demo\TestGetLastLine2.cmd ====================
<Win2000> c:\cmd>demo\TestGetLastLine2 d:\banway\2003-12-31.log
8:39:20.60
8:39:24.11
<Win2000> c:\cmd>rlist demo\TestGetLastLine1.cmd
=====begin c:\cmd\demo\TestGetLastLine1.cmd ====================
1. @echo off
2. echo %time%
3. for /f %%a in ('find /v /c "" ^< %1') do set /a linecount=%%a
4. set /a linecount-=1
5. for /f "tokens=*" %%a in ('more /e +%linecount% %1') do set last_line=%%a
6. echo %time%
=====end c:\cmd\demo\TestGetLastLine1.cmd ====================
<Win2000> c:\cmd>demo\TestGetLastLine1 d:\banway\2003-12-31.log
8:39:47.75
8:39:47.96
> In article <w5UIb.27587$VW.12...@news3.tin.it>, Uno <nos...@sfth.net> wrote:
>
>>for /f "tokens=1 delims=:" %%a in ('findstr /n "\<*" "%1"') do set n=%%a
>
>
> That line count version gives me the idea for yet one formulation
> for getting the Nth line:
>
> @echo off & setlocal enableextensions enabledelayedexpansion
> :: Make a test file
> for %%f in (mytest.txt mytemp.txt) do if exist %%f del %%f
> for %%f in (1 2 3 4 5 6 7 8 9) do echo This is: line %%f>>mytest.txt
> ::
> set /a GetLineNumber=5
> for /f "tokens=1,* delims=:" %%a in ('findstr /n "\<*" "mytest.txt"') do (
> set /a LineCount_=%%a
> if !LineCount_! EQU %GetLineNumber% set line_=%%b)
> echo %line_%
> ::
> :: Clean up
> for %%f in (mytest.txt mytemp.txt) do if exist %%f del %%f
> endlocal & goto :EOF
>
> The output will be
> D:\TEST>cmdfaq
> This is: line 5
>
> All the best, Timo
>
Hi, Timo,
Again, it seems that file size makes an immense difference in the results.
- - - - - - - - - - begin screen capture - - - - - - - - - -
<Win2000> c:\cmd>dir d:\banway\2003-12-31.log | find "/"
01/01/04 02:02a 174,878 2003-12-31.log
<Win2000> c:\cmd>reccount d:\banway\2003-12-31.log .
File d:\banway\2003-12-31.log has 2981 records.
<Win2000> c:\cmd>rlist demo\TestGetNthLine1.cmd
=====begin c:\cmd\demo\TestGetNthLine1.cmd ====================
01. @echo off
02. setlocal
03. echo %time%
04. set GetLineNumber=%1
05. set File=%2
06. for /f "tokens=1,* delims=:" %%a in ('findstr /n "\<*" %File%') do (
07. set /a LineCount_=%%a
08. if !LineCount_! EQU %GetLineNumber% set line_=%%b)
09. echo %line_%
10. echo %time%
=====end c:\cmd\demo\TestGetNthLine1.cmd ====================
<Win2000> c:\cmd>demo\TestGetNthLine1 2899 d:\banway\2003-12-31.log
9:11:24.04
2003-12-31 23:20:00.10 c:\cmd\TEST\heartbeat.cmd started.
9:11:28.38
<Win2000> c:\cmd>rlist demo\TestGetNthLine2.cmd
=====begin c:\cmd\demo\TestGetNthLine2.cmd ====================
01. @echo off
02. setlocal
03. echo %time%
04. set GetLineNumber=%1
05. set File=%2
06. set /a StartAt = GetLineNumber - 1
07. more /e +%StartAt% %File%>w0rkfile.$$$
08. set /p Nth_line=<w0rkfile.$$$
09. del w0rkfile.$$$
10. echo %Nth_line%
11. echo %time%
=====end c:\cmd\demo\TestGetNthLine2.cmd ====================
<Win2000> c:\cmd>demo\TestGetNthLine2 2899 d:\banway\2003-12-31.log
9:11:50.94
2003-12-31 23:20:00.10 c:\cmd\TEST\heartbeat.cmd started.
9:11:51.07
<Win2000> c:\cmd>dir d:\junkdir\glemail.log | find "/"
08/04/01 04:57p 1,810,937 glemail.log
<Win2000> c:\cmd>reccount d:\junkdir\glemail.log .
File d:\junkdir\glemail.log has 16949 records.
<Win2000> c:\cmd>demo\TestGetNthLine1 16001 d:\junkdir\glemail.log
9:12:51.12
2001/07/31 11:02:46.10 GLEMAIL5 downloaded BFS.P.BFPGL10D.GECERROR.D010731.T105737 c:\temp\20010731\GECERROR.D010731.T105737.txt
9:17:05.26
<Win2000> c:\cmd>demo\TestGetNthLine2 16001 d:\junkdir\glemail.log
9:20:33.06
2001/07/31 11:02:46.10 GLEMAIL5 downloaded BFS.P.BFPGL10D.GECERROR.D010731.T105737 c:\temp\20010731\GECERROR.D010731.T105737.txt
9:20:33.76
> Again, it seems that file size makes an immense difference in the results.
> 04. set GetLineNumber=%1
> 05. set File=%2
> 06. set /a StartAt = GetLineNumber - 1
> 07. more /e +%StartAt% %File%>w0rkfile.$$$
> 08. set /p Nth_line=<w0rkfile.$$$
> 09. del w0rkfile.$$$
> 10. echo %Nth_line%
Thank you. That faster alternative is the idea I have been looking
for! The lines 7 and 8 clearly are the ones that essentially do the
trick.
Of course, if one would want really fast, one would use specialized
programs or SED or GAWK. But what you have posted make a very
instructive scripting demonstrations. This is, as it should, more
about scripting e.g. for the FAQ than the actual task. Good.
> Again, it seems that file size makes an immense difference in the results.
> 06. set /a StartAt = GetLineNumber - 1
> 07. more /e +%StartAt% %File%>w0rkfile.$$$
> 08. set /p Nth_line=<w0rkfile.$$$
Below is what I eventually wanted to do. I do hope that I have
managed to pick up the fast components. And thank you, again.
DRAFT
49) I need to reverse a text file. How do I do that fairly quickly?
This item benefits from a discussion in the news:alt.msdos.batch.nt
as per the earlier item #23. The code needed is relatively brief. It
also introduces the use of FOR /L for the first time in this FAQ.
@echo off & setlocal enableextensions
:: Make a test file
set fileName=mytest.txt
for %%f in (%fileName% %temp%\mytemp.txt) do if exist %%f del %%f
for %%f in (1 2 3 4 5 6 7 8 9) do echo This is line %%f>>%fileName%
::
:: Get the number of lines
for /f %%a in ('find /v /c "" ^< %fileName%') do set /a lineCount=%%a
::
for /l %%a in (%lineCount%,-1,1) do call :OutputOneLine %%a
::
:: Clean up
for %%f in (%fileName% %temp%\mytemp.txt) do if exist %%f del %%f
endlocal & goto :EOF
@echo off & setlocal enableextensions
:: ===============================================================
:OutputOneLine
set /a StartAt = %1 - 1
more /e +%StartAt% %fileName%>%temp%\mytemp.txt
set /p Nth_line=<%temp%\mytemp.txt
echo %Nth_line%
endlocal & goto :EOF
The output is
D:\TEST>cmdfaq
This is line 9
This is line 8
This is line 7
This is line 6
This is line 5
This is line 4
This is line 3
This is line 2
This is line 1
--------------------------------------------------------------------
Another solution:
set l=
set /a n_=5-1
for /f "tokens=*" %%a in ('more +%n_% ^< mytest.txt') do (if not defined l set "l=%%a")
echo.%l%