Sign in to follow this  
Followers 0
SadBunny

I really miss the linux 'grep' commandline utility...

5 posts in this topic

#1 ·  Posted (edited)

Hi. Since I really miss the linux 'grep' commandline utility when working under Windows cmd.exe (the MSDOS prompt), I made a simple one for use in the Windows cmd.exe...

Note that the in order to work, the script needs to be compiled to an exe file as a CUI (instead of GUI, done automatically by the #AutoIt3Wrapper_Change2CUI=y) and placed in a directory in your path or your working directory! And ofcourse, use it from a dos prompt! :)

Just run 'grep' with no arguments to get a syntax description!

Here is the code, further below is some dos prompt output with examples of all possibilities.

#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <String.au3>
#include <Array.au3>

If $CmdLineRaw = "" Or $CmdLineRaw = " " Then
 ConsoleWrite(@CRLF & _
   ' grep-like commandline utility for Windows - by SadBunny - thanks to AutoIt3!' & @CRLF & _
   @CRLF & _
   'Usage:' & @CRLF & _
   @CRLF & _
   ' grep text1 text2 text3' & @CRLF & _
   ' grep /s text1 text2 text3' & @CRLF & _
   ' grep /r regexp_pattern' & @CRLF & _
   @CRLF & _
   ' no parameters: list all stdin lines containing the string "text1 text2 text3"' & @CRLF & _
   ' /s (separate): list stdin lines containing "text1" or "text2" or "text3"' & @CRLF & _
   ' /r (regexp)  : list stdin lines fitting regexp_pattern' & @CRLF & _
   @CRLF & _
   ' NOTE: with /r, use _exactly_ two parameters! Use quotes if needed!' & @CRLF & _
   @CRLF & _
   'Examples:' & @CRLF & _
   @CRLF & _
   ' dir c:\ | grep windows' & @CRLF & _
   ' dir c:\ | grep /s settings files windows' & @CRLF & _
   ' dir c:\ | grep /r "(?i)(win|and)"' & @CRLF)
 Exit
EndIf

Local $data
Do
 Sleep(100)
 $data &= ConsoleRead()
Until @error ; wait until no stdin can be read

If $data = "" Then
 ConsoleWrite(@LF & " grep: no stdin to read!" & @LF)
 Exit
EndIf

$stdinArray = _StringSplit($data, @LF, 1) ; put all read stdin data, separated by LineFeed characters, in an array

Local $result
If $CmdLine[1] = "/s" Then ; treat all commandline parameters but the first (which is "/s") as single search strings
 For $i In $stdinArray
  For $j = 2 To $CmdLine[0] ; start at 2 because parameter 1 will always be "/s" and is not a search string
   If StringInStr($i, $CmdLine[$j], 2) Then
    $result &= $i & @LF
    ContinueLoop 2
   EndIf
  Next
 Next
ElseIf $CmdLine[1] = "/r" Then ; treat 2nd parameter as regexp search pattern
 If $CmdLine[0] = 1 Or $CmdLine[0]>2 Then
  ConsoleWrite(@LF & ' grep: regexp syntax: grep /r pattern' & @LF&@LF&' NOTE: with /r, use _exactly_ two parameters! Use quotes if needed!' & @LF)
  Exit
 EndIf
 For $i In $stdinArray
  If StringRegExp($i,$CmdLine[2]) Then $result &= $i & @LF
 Next
Else ; treat full raw commandline ($CmdLineRaw) as one big search string
 For $i In $stdinArray
  If StringInStr($i, $CmdLineRaw, 2) Then $result &= $i & @LF
 Next
EndIf

$resultArray = _StringSplit($result, @LF, 1)

If UBound($resultArray) < 2 Then ; no matches found, first element is always empty due to that _StringSplit call
 ConsoleWrite(@LF & " grep: no matches!" & @LF)
 Exit
EndIf

ConsoleWrite(@CRLF) ; write leading whiteline if any output
For $i In $resultArray
 ConsoleWrite($i & @CRLF)
Next

ConsoleWrite(" grep: number of matches: " & UBound($resultArray) - 1 & @CRLF)

Here is the output of all possibilities on the commandline:

CODE
D:\_AutoIt\_Projects>grep

grep-like commandline utility for Windows - by SadBunny - thanks to AutoIt3!

Usage:

grep text1 text2 text3

grep /s text1 text2 text3

grep /r regexp_pattern

no parameters: list all stdin lines containing the string "text1 text2 text3"

/s (separate): list stdin lines containing "text1" or "text2" or "text3"

/r (regexp) : list stdin lines fitting regexp_pattern

NOTE: with /r, use _exactly_ two parameters! Use quotes if needed!

Examples:

dir c:\ | grep windows

dir c:\ | grep /s settings files windows

dir c:\ | grep /r "(?i)(win|and)"

D:\_AutoIt\_Projects>dir c:\ | grep windows

24-06-2008 23:16 <DIR> WINDOWS

grep: number of matches: 1

D:\_AutoIt\_Projects>dir c:\ | grep /s settings files windows

22-05-2008 12:37 <DIR> Documents and Settings

18-06-2008 06:44 <DIR> Program Files

24-06-2008 23:16 <DIR> WINDOWS

grep: number of matches: 3

D:\_AutoIt\_Projects>dir c:\ | grep /r "(?i)(win|and)"

01-01-1980 01:12 25.308 COMMAND.COM

21-06-2008 02:28 2.855 COMMAND.PIF

22-05-2008 12:37 <DIR> Documents and Settings

24-06-2008 23:16 <DIR> WINDOWS

13 bestand(en) 360.650 bytes

grep: number of matches: 5

D:\_AutoIt\_Projects>

/edit: small bugfix where lines were counted multiple times if fitting more than one single search string when using the /s switch

Edited by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites



Hello,

your script looks very nice, I like it - notably the elegant reading of stdin.

In case you need to grep very large files, you might want to use windows grep

from unix tools, found at http://unxutils.sourceforge.net/. There are a lot more

command line tools included, if you are accustomed to unix, you probably will like them.

ciao

Xandl

Share this post


Link to post
Share on other sites

Thanks! :) I knew there had to be unix tools for windows freely available on the net, but I wanted to try it myself in AutoIt3 :P Thanks for the hint though.

I was just trying to use stdin/stdout in dosbox when I thought of this exercise.


Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites

By the way: "Maximum string length is 2147483647 characters" :)

I think I will not be using anything that produces more than 2 GB of standard output any time soon, let alone wanting to 'grep' it if I do :P


Roses are FF0000, violets are 0000FF... All my base are belong to you.

Share this post


Link to post
Share on other sites

By the way: "Maximum string length is 2147483647 characters" :)

I think I will not be using anything that produces more than 2 GB of standard output any time soon, let alone wanting to 'grep' it if I do :P

Hello SadBunny,

Thank you for sharing your idea and script. I am in the process of creating an autoit gui which allows the user to enter there own multiple command-line queries. So I am very interested in anything that can be ran from a dos prompt which can help maintain servers in a domain or gather and manipulate data. I will be watching this thread for more.

Thanks again,

taurus905


"Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0