1

I am very close to my answer, but I cant seem to find it. I am using the Findstr function in a batch file to narrow now an entire directory to just one file.

cd ...
findstr /s /m "Desktop" *class.asasm >results1.txt
findstr /m /f:results1.txt "Production" *class.asasm >results2.txt
findstr /n /f:results2.txt "Capabilities" *class.asasm >results3.txt

TASK 1: I need to figure out a way to make findstr search backwards for a fourth string from the line number the third line was found on

TASK 2: I need to write lines 1-the one we arrive at of the file in results2.txt the insert a .txt file. Then write the rest of the original lines.

I am writing an application in VB.Net with Visual Studios and I am having a difficult time figuring out how to complete this process. I am currently having better luch with having the application run batch files that are written within the application.

Endoro
  • 37,015
  • 8
  • 50
  • 63
Matt
  • 170
  • 1
  • 2
  • 15
  • What does this have to do with `vb.net`? This might be useful: http://stackoverflow.com/q/8844868/62576 – Ken White Jun 22 '13 at 03:01
  • Thanks I have read that posting and it was very helpful, but I still have not found a way to search starting at line xx rather than 1 or to search in reverse order. I didn't find either capability referenced there – Matt Jun 22 '13 at 03:10
  • You're assuming it's possible to search backward using `findstr`, which isn't evident anywhere that I can see. Perhaps you should find the right tool for the task at hand. Also, I still see no indication that `vb.net` is an applicable tag here. (`windows` is probably not needed, either; `cmd` and `batch-file` are enough to indicate it's not *nix or Mac.) – Ken White Jun 22 '13 at 03:14
  • I removed the other two tags as you make a valid point. I am still in need of a function that can search backwards and print the line number of the first result only. It seems straight forward to me that there would be a cmd function for this since it has been around forever in windows (ctrl +f) – Matt Jun 22 '13 at 03:22
  • I'd suggest you rethink what you're asking, then. Your question is actually something other than "How do I do this with findstr?", because `findstr` wasn't the proper option in the first place. There are ways to iterate through file contents in VB.Net without resorting to `findstr` and `cmd`, and `findstr` hasn't been around near as long as the Windows command line (since Windows 1.0) has existed. You can read entire files into your code and work with them without resorting to using the command line much more easily. – Ken White Jun 22 '13 at 03:33
  • Please explain what your objective is, clearly, with examples. Using `/f:...` AND the filemask *class.asasm makes little sense - it scans all files matching the mask AS WELL AS those filtered into the file, so `results2` contains a list of files containing `Desktop` OR `Production` - easier done with `"Desktop Production"` - but I suspect you want the files that match BOTH, – Magoo Jun 22 '13 at 04:36
  • then find the line(s?) containing "Capabilities". Then you want to find some mysterious string that occurs (or may occur?) before the line where "Capabilities" was found (but not after?) and then write lines 1 to the mystery line ` the insert a .txt file.` (What does this mean?) Then write the rest of the original lines? That would mean write all of the lines - 1 to the mystery line, then the rest of the original lines. Write it to where? All in the same file? Different files? Please clarify. – Magoo Jun 22 '13 at 04:36
  • `findstr` doesn't search "backwards", it searches `recursively` (from the current folder to the last subfolder). – Endoro Jun 22 '13 at 05:33

2 Answers2

2

The correct solution is to find a tool that does this properly. batch/CMD does not.

Here's a script that tells you the line numbers of the 3rd and 4th match. It's probably not exactly what you want, but it is a demonstration of how one can effectively work with line numbers.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET FILE=TestFile.txt

SET _LINENO=1
SET _MATCHNO=0
SET _THIRDLINENUM=
SET _FOURTHLINENUM=
FOR /F %%l IN (%FILE%) DO (
   ECHO %%l | FINDSTR "Target" %_TMP% >NUL
   IF NOT ERRORLEVEL 1 (
      SET /A _MATCHNO=!_MATCHNO!+1
      IF !_MATCHNO!==3 SET _THIRDLINENUM=!_LINENO!
      IF !_MATCHNO!==4 SET _FOURTHLINENUM=!_LINENO!
   )
   SET /A _LINENO=!_LINENO!+1
)

@ECHO %_THIRDLINENUM% : %_FOURTHLINENUM%

Here's what's in TestFile.txt

abcdefg
bcdefgh
Target 1
cdefghi
defghij
fghijkl
Target 2
ghijklm
hijklmn
ijklmno
jklmnop
klmnopq
lmnopqr
mnopqrs
Target 3
nopqrst
Target 4
opqrstu
pqrstuv
qrstuvw
rstuvwx
stuvwxy
tuvwxyz

If you insist on using batch/CMD (and I sometimes do when nothing else is available), and you need to get the text on line #n (otherwise, head and tail would do just fine), you could produce a similar loop but replace the code from FINDSTR down to the end of the IF statement with something that compares _LINENO with some other variable, ECHO'ing the line if it is between the two values. I don't know if IF supports logical operators, so you may have to nest the IF statements, like

IF !_LINENO! GEQ %START_LINE% IF !_LINENO! LEQ %END_LINE% @ECHO %%l
mojo
  • 4,050
  • 17
  • 24
2

assuming you need this (from your first comment):

I still have not found a way to search starting at line xx rather than 1 or to search in reverse order

you can try this (from the command line):

for /r %i in ("file pattern") do @more "%~i" +starting_line |findstr  "search string"
  • for /r = recursively (if you mean really reverse, please explain)
  • "file pattern" = files to find, eg. "*class.asasm"
  • starting_line = search starting line, eg. 7 (more +6)
  • "search string" = your search pattern, eg. "Desktop"
    • OR search "Desktop Production Capabilities"
    • AND search |findstr "Desktop"|findstr "Production"|findstr "Capabilities"
Endoro
  • 37,015
  • 8
  • 50
  • 63