Colouring the Command Prompt

A long time ago I wrote some really basic code to colour the output displayed in the Windows cmd.exe. I’ve just come across it hidden in one of my folders and thought I’d resurrect it since it’s something I’d like to look at in PowerShell when I have the opportunity (although changing the colour in PowerShell is easy with Out-Host.) The tool was originally knocked together because I’d wrapped grep.exe in a batch file but wasn’t happy with the output – I wanted matching strings that I was searching for to be highlighted in different colours.

As an example here’s some test text…

This is a <style textcolour='red'>quick</style> test to <style textcolour='Blue'>see if</style>
the colourise utility works and identifies
<style textcolour='Yellow'>all</style> the necessary items.
This is a test to check <style textcolour='Magenta'>it matches colours at the end.</style>
<style textcolour='Yellow'>This has <style textcolour='Red'>nested <style textcolour='Blue'>colouring</style> that </style> currently </style> isn't supported.

which renders as :

image

Note that nested styles are not supported.

The code to accomplish this is below.

 

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace Colourise
{
    class Program
    {
        static void Main(string[] args)
        {
            string lineInput;
            while ((lineInput = Console.ReadLine()) != null)
            {
                Stack<ConsoleColor> oldColourStack = new Stack<ConsoleColor>();
                Regex rx = new Regex(@"(?<pretext>.*?)<style textcolour='(?<colour>[^']*)'>(?<colouredtext>.*?)</style>(?<posttext>.*?)");
                MatchCollection matches = rx.Matches(lineInput);
                if (matches.Count > 0)
                {
                    foreach (Match match in matches)
                    {
                        Console.Write(match.Groups["pretext"].Value);
                        oldColourStack.Push(Console.ForegroundColor);
                        Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), match.Groups["colour"].Value, true);
                        Console.Write(match.Groups["colouredtext"].Value);
                        Console.ForegroundColor = oldColourStack.Pop();
                        Console.Write(match.Groups["posttext"].Value);
                    }
                    Match lastmatch = matches[matches.Count - 1];
                    Console.WriteLine(lineInput.Substring(lastmatch.Index + lastmatch.Length));
                }
                else
                {
                    Console.WriteLine(lineInput);
                }
            }
        }
    }
}

Fixing Windows Media Using PowerShell

I made a blunder a while back… I sync’d my laptop with my backup external hard drive but accidentally sync’d with a folder of music that contained compressed versions of the same music!!

I may well have been able to do this in an easier fashion but I’m in the market for learning PowerShell and therefore thought I’d give it a go. Initially I focused on wanting to compare files with the same name (but different file extensions) and only delete those where the bitrates were smaller. However, reading the file tag information didn’t seem to be the easiest of things and probably required writing a C# class (www.codeproject.com offers a variety) but they all required extra dependencies including the Windows Media Format SDK from Microsoft which I didn’t really want to have to use at this point.

So I moved onto my next plan. Luckily for me the smaller files had been compressed as .wma files whilst my originals were .mp3. I could probably have just deleted everything that was .wma but I wanted to be sure I hadn’t ripped anything as wma instead of mp3. So, the following script compares files with the same filenames but different extensions and deletes the .wma file if it exists and it’s smaller than the mp3 I’m comparing it with. Nothing spectacular but it got the job done and I’ve made another step toward learning PowerShell.

Get-ChildItem -Recurse -Include *.mp3 | ForEach-Object -Process { 
    $file = $_.Directory.ToString() + "\" + $_.Name.Substring(0, $_.Name.LastIndexOf(".")) + ".wma"; 
    $fileinfo = New-Object -TypeName System.IO.FileInfo -ArgumentList $file; 
    if ($fileinfo.Exists -and $fileinfo.Length -le $_.Length) { 
        $fileinfo.MoveTo('C:\\Temp\\SongsToDelete\\' + $fileinfo.Name) 
    } 
}