DosTips.com

A Forum all about DOS Batch
It is currently 18 Oct 2017 05:24

All times are UTC-06:00




Post new topic  Reply to topic  [ 2 posts ] 
Author Message
PostPosted: 19 Jan 2012 13:05 
Offline
Expert

Joined: 06 Dec 2011 22:15
Posts: 1448
Location: México City, México
In this topic I presented TYPEOFHANDLE.COM program that get status information from the standard handles. However, a .COM program may also modify certain handle status that persists after the .COM program ends; for example, the File Pointer position.
Code: Select all
SETFILEPOINTER handle position
This program move handle's File Pointer to the position given in bytes. Use 0 to BOF; use an E letter to indicate EOF.

SETFILEPOINTER program allows to read lines from the redirected input file in any order via the starting position of each line. These positions can be obtained just once and stored in an auxiliary file to be used several times:
Code: Select all
:CreateLinePositions
set position=0
:nextLine
   echo %position%
   set line=
   set /P line=
   call :StrLen line lineLen=
   set /A position+=lineLen+2
   TypeOfHandle 0
   set /A eof=%errorlevel% ^& 64
if %eof% == 0 goto nextLine
exit /B
File lines must end in CR+LF characters (Windows style) and must not have trailing control characters; also, they must not exceed the maximum SET /P input length of 1021 characters.

EDIT: I realized that previous process may be achieved in a simpler way via FINDSTR /O command this way:
Code: Select all
:CreateLinePositions
for /F "delims=:" %%a in ('findstr /O "^"') do echo %%a
exit /B

By convention, we will use .DEX extension for line-position files. For example, this data file:
Days.txt wrote:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
... with this command:
Code: Select all
call :CreateLinePositions < Days.txt > lines.dex
... generate this index file:
lines.dex wrote:
0
8
16
25
36
46
54
A data file may have several index files that allows to process the data in different orders. The following subroutine use the Bubble Sort method to sort the indexes of the lines, but does not modify the file itself:
Code: Select all
:BubbleSort baseIndex < inputFile > resultIndex
setlocal EnableDelayedExpansion
set n=0
for /F %%p in (%1) do (
   set /A n+=1
   set linePos[!n!]=%%p
)
:bubblePass
   set anyChange=
   set one=1
   setFilePointer 0 !linePos[1]!
   set /P line1=
   for /L %%i in (2,1,%n%) do (
      setFilePointer 0 !linePos[%%i]!
      set /P line2=
      if "!line1!" gtr "!line2!" (
         set /A temp=linePos[!one!], linePos[!one!]=linePos[%%i], linePos[%%i]=temp
         set "line2=!line1!"
         set anyChange=True
      )
      set /A one+=1
      set "line1=!line2!"
   )
if defined anyChange goto bubblePass
for /L %%i in (1,1,%n%) do echo !linePos[%%i]!
exit /B
For example, this command:
Code: Select all
call :BubbleSort lines.dex < Days.txt > alpha.dex
... create this index file:
alpha.dex wrote:
46
8
54
0
36
16
25
... so this code:
Code: Select all
< Days.txt (
   for /F %%p in (alpha.dex) do (
      setFilePointer 0 %%p
      set /P line=
      echo !line!
   )
)
... display this result:
DaysInAlphaOrder.txt wrote:
Friday
Monday
Saturday
Sunday
Thursday
Tuesday
Wednesday

A data file may also contain the position of a field located in another data file, like a rudimentary Relational Data Base (see this post).

This method also allows to modify data in a redirected output file in any place of the file, not just appending data at the end. To do that, just move the File Pointer of handle 1 to the desired position before output the new data:
Code: Select all
(
   setFilePointer 1 46
   echo Line 6
) >> Days.txt
Result:
Result wrote:
Sunday
Monday
Tuesday
Wednesday
Thursday
Line 6
Saturday
Remember that the repetitive execution of .COM end .EXE executable programs is achieved faster if the DOS Window is maximized with Alt-Enter key. This is the complete SETFILEPOINTER.COM test program:
Code: Select all
@echo off
::SETFILEPOINTER.COM test program
::Antonio Perez Ayala - Jan/19/2012

setlocal EnableDelayedExpansion

if not exist SetFilePointer.com call :CreateSetFilePointer

cls

echo Days.txt:
(
echo Sunday
echo Monday
echo Tuesday
echo Wednesday
echo Thursday
echo Friday
echo Saturday
) > Days.txt
type Days.txt
echo/

echo lines.dex:
call :CreateLinePositions < Days.txt > lines.dex
type lines.dex
echo/

echo alpha.dex:
call :BubbleSort lines.dex < Days.txt > alpha.dex
type alpha.dex
echo/

echo DaysInAlphaOrder:
< Days.txt (
   for /F %%p in (alpha.dex) do (
      setFilePointer 0 %%p
      set /P line=
      echo !line!
   )
)
echo/

echo Line 6 of Days.txt modified:
(
   setFilePointer 1 46
   echo Line 6
) >> Days.txt
type Days.txt

goto :EOF


:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


:CreateSetFilePointer
setlocal DisableDelayedExpansion
set SetFilePointer=2ÿ³‹û‹ó2íŠMÿãE° üó®t^>Š]ÿ€û0r6€û9w1€ë0Sã+€= u^&ó®t"Of3Àf3ɱ+€é!f3ÛGŠ]ÿ€ûEt+€ûeu(uÿë%%ëyGf3ÛŠ]ÿ€û0rs€û9wnf÷á€ë0f÷Ûf+ÃëáëØëäf‹È2Àf#ÉuTþÀþÀ€<EtK€<etFFÆDÿB‹Ñ±1€é!fÓé[´BÍ!r­€|ÿBu§±1€é!fÓâ‹Ðf÷Úf‹Ê±1€é!fÓé2ÀþÀþÀ´BÍ!2À´LÍ!ë¢ë½
setlocal EnableDelayedExpansion
echo !SetFilePointer!> SetFilePointer.com
exit /B


:CreateLinePositions < inputFile > baseIndex
for /F "delims=:" %%a in ('findstr /O "^"') do echo %%a
exit /B


:BubbleSort baseIndex < inputFile > resultIndex
setlocal EnableDelayedExpansion
set n=0
for /F %%p in (%1) do (
   set /A n+=1
   set linePos[!n!]=%%p
)
:bubblePass
   set anyChange=
   set one=1
   setFilePointer 0 !linePos[1]!
   set /P line1=
   for /L %%i in (2,1,%n%) do (
      setFilePointer 0 !linePos[%%i]!
      set /P line2=
      if "!line1!" gtr "!line2!" (
         set /A temp=linePos[!one!], linePos[!one!]=linePos[%%i], linePos[%%i]=temp
         set "line2=!line1!"
         set anyChange=True
      )
      set /A one+=1
      set "line1=!line2!"
   )
if defined anyChange goto bubblePass
for /L %%i in (1,1,%n%) do echo !linePos[%%i]!
exit /B


Last edited by Aacini on 14 Apr 2014 09:26, edited 2 times in total.

Top
   
PostPosted: 19 Jan 2012 13:15 
Offline
Expert

Joined: 16 May 2011 08:21
Posts: 1438
Location: Flanders(Belgium)
'
I use to read ini files a lot, I use the [ ] for pattern search and replace.

Can't use this right now but, dBenham points out, someday I might run into problems with findstr.EXE so maybe...

Pretty cool :wink: :!:


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 2 posts ] 

All times are UTC-06:00


Who is online

Users browsing this forum: No registered users and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited