line numbers in find vs findstr

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
spodermon
Posts: 6
Joined: 27 Dec 2016 17:47

line numbers in find vs findstr

#1 Post by spodermon » 27 Dec 2016 18:07

Hello everyone.

After struggling for a little while with a batch that is printing the wrong lines I did some tests and found that for some reason 'find' and 'findstr' are giving me different line numbers for a specific line. Has anyone seen this?

c:\Temp\S>type supportshow.txt | find /N "portshow 0"
[14580]portshow 0

c:\Temp\S>type supportshow.txt | findstr /R /I /B /N /C:"portshow 0"
14320:portshow 0

if I open the file with Notepad++ the correct line number is the one given by findstr, but if then I try to print that line it prints another line entirely different. And the thing is, I found a loop somewhere on the internet that does this print specific line thing, but it works with 'find' that's why I think its printing the wrong line.

The for loop I'm using to print the lines is:
for /f "tokens=1,* delims=]" %v in ('find /n /v "" ^< "supportshow.txt" ^| findstr "^\[14580\]" ') do echo %w
(I don't fully understand this line so I haven't been able to change it, 14580 is the line I'm trying to print)

So... does anyone know why find and findstr give different line numbers? is there a modifier that I could use so that ignore whatever is making then count differently? the source file was created by having putty save the output of an ssh session (perhaps putty is adding an invisible character or something?)

or, does anyone know of another way to print a specific line of a file that doesn't rely on 'find'?

Thanks!

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: line numbers in find vs findstr

#2 Post by Sponge Belly » 28 Dec 2016 09:24

Hi Spodermon! :)

Happy Christmas and welcome to the forum.

Paste the following (untested) code into an empty Notepad window and save the file as lineNo.cmd:

Code: Select all

@echo off & setlocal enableextensions disabledelayedexpansion

for /f "delims=:" %%A in ('
findstr /bilnc:"portshow 0" "%tmp%\supportshow.txt"
') do set "lineNo=%%A"

echo(match found on line %lineNo%

endlocal & exit /b 0


Run the file and it will display the line number of the last line in "supports.txt" containing the string "ports 0". I’m assuming "supports.txt" is in the "%tmp%" folder.

Switches for findstr (and xcopy) can be grouped. Findstr also accepts a file name as argument. No need to use pipes or redirection.

HTH!

- SB

spodermon
Posts: 6
Joined: 27 Dec 2016 17:47

Re: line numbers in find vs findstr

#3 Post by spodermon » 28 Dec 2016 10:37

Thanks Sponge Belly.

I did as you suggested, and the output of the script find the line on 14320:

c:\Temp\S>lineno
match found on line 14320

as a test, I modified the script you shared to use 'find' instead 'findstr', and again its giving me a different result...

(after the modification:)
c:\Temp\S>lineno
match found on line [14580]portshow 0

the modification was just change findstr with find:

Code: Select all

@echo off & setlocal enableextensions disabledelayedexpansion

for /f "delims=:" %%A in ('
find /n "portshow 0" "c:\temp\s\supportshow.txt"
') do set "lineNo=%%A"

echo(match found on line %lineNo%

endlocal & exit /b 0


So, I'm still at a loss, why are they giving different outputs and how do I make them be the same. I'm guessing there's something wrong on the source file, probably some character find is interpreting as a line break and findstr isn't? any way to "clean" the file?

Maybe someone is thinking "why do you need them to be same, pick one and continue working with it!"
I need findstr because it has a modifier to look for the text at the beginning of the line, and I need find because that's the way I have to print a specific line. if anyone has an alternative to any of those things I'm good with it.

Thanks!

spodermon
Posts: 6
Joined: 27 Dec 2016 17:47

Re: line numbers in find vs findstr

#4 Post by spodermon » 28 Dec 2016 10:59

Ok, so I went digging into the source file and I found one of the "problem lines".

if I open the source file on notepad it looks ok, but if I open it in Notepad++ a "nul" icon is displayed. before this line both find and findstr match all the line numbers, after this line they are skewed by one line (skewed? is that the right word? sorry, not English native speaker here).

The forum does not allow me to upload a txt file, but I'm attaching an screenshot of the problematic line as seen on notepad vs Notepad++, also, adding the lines as code, just in case it helps somehow...

Code: Select all

21:49:05 454131936 Number of rules: 8
21:49:05 454131936 IPC returns : 0
 
seccertutil show -all      :
Permission denied to perform this operation.

pkishow        :


any ideas how to clean the file?
Attachments
2016-12-28_105642.png
Line 3 is the problematic one
2016-12-28_105642.png (16.6 KiB) Viewed 15690 times

Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

Re: line numbers in find vs findstr

#5 Post by Sounak@9434 » 28 Dec 2016 12:35

If you are just looking for an easy solution just remove the lines with nul using notepad++ and replace with the enter key or what you want.
By the way you can just compress the txt file in zip file, then you can upload it here.

spodermon
Posts: 6
Joined: 27 Dec 2016 17:47

Re: line numbers in find vs findstr

#6 Post by spodermon » 28 Dec 2016 12:55

Thanks Sounak.

I'm indeed looking for an easy solution, but I'm looking for something that can be run automatically, on the same script if at all posible

The script I'm trying to do will extract information from these kind of source files, do some processing and give a csv file for easy reading, but the source files are usually created the same way, by running a command on an ssh session and saving the output so this "nul" lines will most likely by an ongoing thing.

Any ideas?

spodermon
Posts: 6
Joined: 27 Dec 2016 17:47

Re: line numbers in find vs findstr

#7 Post by spodermon » 28 Dec 2016 14:16

Forgot to attach file.
Attachments
problemline.zip
3rd line is the problem one
(295 Bytes) Downloaded 503 times

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: line numbers in find vs findstr

#8 Post by aGerman » 28 Dec 2016 14:36

Dave's JREPL utility can certainly remove the null bytes
viewtopic.php?f=3&t=6044

Code: Select all

jrepl "\x00" "" /m /f "problemline.txt" /o -

Steffen

spodermon
Posts: 6
Joined: 27 Dec 2016 17:47

Re: line numbers in find vs findstr

#9 Post by spodermon » 28 Dec 2016 17:44

Thanks aGerman!

I found another workaround.

I found that powershell counts the lines the same way findstr does, so I'm using it to print the lines I wanted to print. I added this to my script:

Code: Select all

powershell "get-content %1 | select -first !dife! -skip !portline!"


Where !portline! is the first line I want to print and !dife! holds the number of lines I want to print. Its also way faster. instead of doing a loop and printing line by line like i was doing, PS just throws everything in a single pass.

Hopefully using PS in a batch wont come back and bite me in the ... :)

Thanks everyone.

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: line numbers in find vs findstr

#10 Post by ShadowThief » 28 Dec 2016 18:29

As long as you're running it on a computer that's running XP or later, you'll be fine with a batch/powershell hybrid.

Sponge Belly
Posts: 231
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: line numbers in find vs findstr

#11 Post by Sponge Belly » 31 Dec 2016 14:25

Hi Again,

Null characters are notoriously difficult to deal with, as discussed in Robust Line Counter. If an input text file is contaminated with null characters, the best course of action is to get rid of them. But if that isn’t possible, there are workarounds.

For example, the following snippet accepts 2 arguments: a filename, and a case-insensitive literal string to search for.

Code: Select all

@echo off & setlocal enableextensions disabledelayedexpansion

set "lnFile=%tmp%\lineNums.tmp"
>"%lnFile%" echo(0:
set "stop="

echo( | cmd /q /c for /l %%I in (^) do if not defined stop (^
set "stop=1" ^& for /f "tokens=2 delims==:" %%N in (^
'"findstr /ilnc:"%~2" "%~1" | findstr /blvg:"%lnFile%" | more | set /p no=^&^& set no"'^) ^
do (set "stop=" ^& echo(%%N ^& echo(%%N^>^>"%lnFile%"^)^) else exit 0

del "%lnFile%"

endlocal & goto :eof


This is a hugely inefficient way to search a file, but its one redeeming quality is that it won’t be tripped up by the presence of null characters.

Best wishes to all for a happy and peaceful 2017! :)

- SB

Post Reply