September 25, 2009

Grep is the quintessential unix utility: it has a funny name, has more command-line switches than a Swiss Army knife has blades, and dates to prehistoric times. In its simplest incarnation, grep takes a regular expression and a file and prints those lines of the file that match the regular expression.

Since we wrote a regular-expression matcher in the three previous exercises, it is easy to write our own version of grep. We’ll keep it simple:

grep [-v] regex [file ...]

The -v flag inverts the sense of the match: print only those lines that do not match the regular expression. One or more files may be named on the command line; if so, the filename is printed before each matching (or non-matching, for -v) line. If no filename is given, grep reads from standard input. All output goes to standard output.

Your task is to write grep. When you are finished, you are welcome to read or run a suggested solution, or to post your solution or discuss the exercise in the comments below.

Pages: 1 2

2 Responses to “Grep”

  1. […] today’s Programming Praxis exercise we’re supposed to implement grep based on the regex matching […]

  2. Remco Niemeijer said

    My Haskell solution (see for a version with comments):

    import System.Environment
    import Text.Printf
    --Code from the previous two exercises goes here
    grepString :: Bool -> Maybe String -> [Chunk] -> String -> IO ()
    grepString b p cs = mapM_ (printf "%s%s\n" $ maybe "" (++ ": ") p) .
                        filter ((== b) . match cs) . lines
    grep :: Bool -> [String] -> IO ()
    grep _ []     = error "Not enough arguments provided"
    grep b (r:ps) = either print (f ps) $ parseRegex r where
        f [] cs = grepString b Nothing cs =<< getLine
        f _  cs = mapM_ (\p -> grepString b (Just p) cs =<< readFile p) ps
    main :: IO ()
    main = f =<< getArgs where
               f ("-v":args) = grep False args
               f args        = grep True  args

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 696 other followers

%d bloggers like this: