Monad script to convert your doskey macros to Monad functions

Last week I talked about how I wanted to write a script to convert my doskey macros into Monad functions. I used this opportunity to learn about writing scripts in Monad. I must say I'm impressed so far, it has been pretty easy to pickup. The one thing that I kept getting burned by and that I don't care for much is the comparison operators. I don't like using -lt, -gt, etc, I'm too used to <, >. At anyrate here is the code (keep in mind that I'm new to Monad scripting so if I did something wrong go easy on me ;) with that said I'm open to suggestions).

# $macro should be of the form <macroname>=<macro> where <macro> supports 
# everything doskey does plus traditional environment variables
function global:doskey([string] $macro, [bool] $verbose=$false)
{
    if($macro -match "^(?<name>[^=]+)=(?<macro>.+)$")
    {
        $cmd = $matches['macro'];
        
        # Escape the quotes
        $cmd = $cmd.Replace('"', '`"').Replace('`'', '```'');
        
        # Replace $1-$9 doskey variables
        for($i = 1; $i -lt 9; $i++)
        {           
            $cmd = $cmd.Replace('$' + $i, '`'+$args[' + ($i-1) + ']+`'');
        }
            
        # Replace $* doskey variable
        $cmd = $cmd.Replace('$*', '`'+$args+`'');
        
        # Replace $T doskey (i.e. command splitter);
        $cmd = $cmd.Replace('$T', '; & ');
        
        # Replace %PATH% environment vars $ENV:PATH
        $cmd = [System.Text.RegularExpressions.Regex]::Replace`
            ($cmd, '%(?<var>.*?)%', '`'+$ENV:${var}+`'');
        
        # wrap the cmd with a call to invoke-command
        $cmd = 'invoke-command(`'& ' + $cmd + '`')';
        
        # Cleanup the empty quotes
        $cmd = $cmd.Replace('+`'`'', '');
        
        # Create a function that represents the doskey macro
        $func = 'function global:' + $matches['name'] + ' { ' + $cmd + ' }';
        
        if($verbose) { echo $func; }
        invoke-command($func);
    }
    else
    {
        echo "ERROR: $macro is not of the form <name>=<macro>";
    }
}

function global:doskeyfile([string] $macrofile, [bool]$verbose=$false) 
{     
    if($macrofile.Length -eq 0 -or !(test-path $macrofile)) 
    { 
        echo "Error: File [$macrofile] does not exist"; 
        return; 
    }
    
    foreach($macro in (get-content $macrofile)) 
    {
        doskey $macro $verbose;
    }
    echo "Finished processing $macrofile."
}

To use this you can save those functions in a .msh script file and then run that script from the prompt. Here are a couple examples of doskey macros and what they get converted to.

Doskey macros

ie="%PROGRAMFILES%\internet explorer\iexplore.exe" $*
echo2=echo "1:$1" $T echo "2:$2"

Monad functions

function global:ie 
	{ invoke-command('& "'+$ENV:PROGRAMFILES+'\internet explorer\iexplore.exe" '+$args) }
function global:echo2 
	{ invoke-command('& echo "1:'+$args[0]+'" ; &  echo "2:'+$args[1]+'"') }

Enjoy!

[Cross posted on my personal blog]

No Comments