Showing posts with label Scripting Games. Show all posts
Showing posts with label Scripting Games. Show all posts

Monday, October 6, 2008

Powershell Count Files By Regex Match on Content

Being a Powershell Winter Scripting Games Top Scorer for both the 2007 and 2008 Scripting Games I have to keep my skills fresh. Never know when you need to whip out an extra dirty little script to count how many T's are in a text file.

Scripting languages always give me a dirty feeling when I get done and look at my code. I'm a fan of what Code Complete describes as the Primary Imperative of Software Engineering; Managing Complexity. Solving something with a scripting language always makes we want to write something using the least amount of characters possible. Comments, descriptive variable names and consistent formatting usually go right out the window along with the ability to come back a month later and figure out what is going on in the script, let alone try and tell a co-worker what is going on.

That being said, here is a tiny powershell script to count files based on a Regex match of their content. Don't worry, I took the time to comment it a little bit and even have some pretty descriptive variable names. It originally was just one line for the specific task I needed to get done. I was looking for the number of xml files with a specific value in a set of directories.


# Create Parameters for our script.
# TODO: Make a helpful usage reply when no parameters supplied.
Param( [String]$path="./",
[String]$filter="*.txt",
[String]$match=$(throw "Regex Pattern required."),
[switch]$searchSubs)

$reg = [regex]$match;

if ( $searchSubs )
{ # Get the files matching the passed in path/filter
dir -path $path -filter $filter -recurse
# Loop through each and look for a match of the Regex.
% {
$in = gc $_.FullName; $reg.Match($in).Groups[1].Value
} group #Group the Values.
}
else
{ dir -path $path -filter $filter
% {
$in = gc $_.FullName; $reg.Match($in).Groups[1].Value
} group
}

Here is some sample usage:

./FileMatch.ps1 -path c:\somewebsite\fileUpload -filter *.xml -match 'field value="(.*?)" name="blah' -searchSubs

You can even mix up the parameters if you want. Powershell Rocks!

Now Playing: Jason Mraz - Curbside Prophet

Friday, July 25, 2008

F# for beginners

I'm trying to get some more breadth to my programming knowledge, so I decided to start looking into F# for some functional programming exposure.

So far, I'm liking what I'm going to call the brevity of the language. I'm not one of those people who thinks that programming languages ought to be made for the "Everyone" programmer, at least not all programming languages. It gives me the impression of condensing the programming down into little mouth-puckering shots of power, akin to some condensed tomato soup or something.

Anyway, to dig a little deeper into the language and actually try and solve problems I decided to try and do the beginner Scripting Games Events from this year in F#. There is already at least one post on another F# blog where someone is doing the first event.

I decided to try and limp through the second event, and here is what I came up with.


#light
open System
open System.IO
open Microsoft.Win32

// Scripting Games Event 2, How many True Type Fonts installed.

// Open the registry key where fonts are stored, using .Net objects
(Registry)
let fontKey =
Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows
NT").OpenSubKey("CurrentVersion").OpenSubKey("Fonts")

// Get the font names, convert to list
let vals = fontKey.GetValueNames() > Seq.to_list

// Defining a recursive "function" that takes a string to match and a list
of strings, returns num of matches
let rec matchEnd (srch : string) (list :
string List) =
match list with
[] -> 0 // Empty list
// The x and xs refer to the head(x) and tail(xs) of the list.
x::xs
when x.Trim().EndsWith(srch) -> (1 + (matchEnd srch xs))
x::xs ->
matchEnd srch xs

// Print the true type fonts, number of fonts, and total fonts.
List.filter (fun (b : string) -> b.Trim().EndsWith("(TrueType)")) vals
> printfn "%A"
printfn "True Type Fonts Installed: %A" (matchEnd
"(TrueType)" vals)
printfn "Total Fonts Installed: %A" vals.Length

// Pause for exit
Console.ReadKey(true)




Sorry for the lack of formatting (which is actually important for the #light syntax). So I think that does the job for Event 2. I'm sure it could be better, but it's just a learning exercise so far.