Return character of specific position in a line

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Return character of specific position in a line

#16 Post by dbenham » 20 Jun 2013 17:49

I'm not addressing your new question, but I do have a much more efficient method to move lines to one of 2 files, depending on value of 10th character.

Simply use FINDSTR with an appropriate regex search string. Do it once to move matching lines, and a 2nd time with /V option to move non-matching lines. It might seem less efficient because each file is read twice. But in reality it will be much faster than any FOR /F loop.

To truly move the line, you should also either delete the original file when done, or at least move the original file to a new location. That way you can re-run your batch script the next day and not get confused by prior day's files.

It is important that the destination files reside in a different folder than the source so as not to mistakenly process the destination files as source material.

Code: Select all

@echo off
setlocal
set "chars=ABCDE"
set "sourceMask=sourcePath\*.txt"
set "matchOutput=destinationPath\match.txt"
set "noMatchOutput=destinationPath\noMatch.txt"

for %F in ("%sourceMask%") do (
  findstr /r  "^.........[%chars%]" "%F" >"%matchOutput%"
  findstr /rv "^.........[%chars%]" "%F" >"%noMatchOutput%"
  REM - I recommend   DEL "%F"   or   MOVE "%F" "newLocation"
)


Dave Benham

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Return character of specific position in a line

#17 Post by penpen » 25 Jun 2013 19:41

Hi,

i hope this post is not too late, but i think the efficiency could be improved by using the buffer capacity of STDIN and STDERR, the match.txt receives the redirected output of STDIN and nomatch.txt that of STDERR.

This solution advantages are:
- not to use more than one file handle per outputfiles, this is because it avoids reopening a file for appending multiple times using >>, and
- findstring is performed only once per file

But i don't know if this solution is slowed down too much by the four for loops... .
I have actually no time, to test that.

Here is the code:
First a batch file named split.bat is needed:

Code: Select all

@echo off
setlocal enabledelayedexpansion
set "CHARS=ABCDE"

for %%a in (in*.txt) do for /F "delims=" %%b in ('findstr "^" "%%a"') do (
  set LINE=%%b
  for %%c in ("!LINE:~9,1!") do for %%d in ("!CHARS:%%~c=!") do (
    if not %%~d == %CHARS% ( echo:%%b
    ) else (echo:%%b)1>&2
  )
)

endlocal
goto:eof


Then you start it with a command line like that:

Code: Select all

split.bat > match.txt 2> nomatch.txt


penpen

Post Reply