Token Replacement in PowerShell

A question I often get asked is why psake does not include something similar to NAnt’s <replacetokens>. The reason is because it’s so darn easy to do it in PowerShell. Given foo.txt.template:

@@foo@@ is @@bar@@!!!

The following script will perform the replacement:

# replace.tokens.ps1
$foo = 'PowerShell'
$bar = 'da bomb'
(cat foo.txt.template) -replace '@@foo@@', "$foo" `
                       -replace '@@bar@@', "$bar" `
                       > foo.txt

(Note the backticks (`) at the end of the line to denote continuation.)

This script will produce:

PowerShell is da bomb!!!

You could easily write a function that would take care of the nitty gritty details. The @@var@@ is arbitrary. You could use any sequence you like. You can even perform regex matches in the @@var@@ expression if needed. Note the double quotes around “$foo”. This is PowerShell for performing variable replacements in strings. So “$foo” results in the word PowerShell whereas ‘$foo’ results in the word $foo.

So there you have it. Token replacement built right into PowerShell. Happy Scripting!

About James Kovacs

James Kovacs is a Technical Evangelist for JetBrains. He is passionate in sharing his knowledge about OO, SOLID, TDD/BDD, testing, object-relational mapping, dependency injection, refactoring, continuous integration, and related techniques. He blogs on CodeBetter.com as well as his own blog, is a technical contributor for Pluralsight, writes articles for MSDN Magazine and CoDe Magazine, and is a frequent speaker at conferences and user groups. He is the creator of psake, a PowerShell-based build automation tool, intended to save developers from XML Hell. James is the Ruby Track Chair for DevTeach, one of Canada’s largest independent developer conferences. He received his Bachelors degree from the University of Toronto and his Masters degree from Harvard University.
This entry was posted in PowerShell. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://jameskovacs.com/ James Kovacs

    @Damien – The replacements are chained. So you are correct that the result given the current ordering would be “@@foo@@ is @@foo@@!!!”. PowerShell supports regex matching as well as simple string matching. You might be able to construct a parallel matcher using the regex support. Honestly the simple matcher suffices in all cases that I’ve encountered and is a lot easier to understand.

  • http://damien.the.unbeliever.myopenid.com/ Damien

    Not sure how <replaceTokens> works, but this is string replacement, correct? so if $foo = ‘@@bar@@’ and $bar = ‘@@foo@@’, then performing the replacements in order produces a final text ‘@@foo@@ is @@foo@@!!!’, correct? Would there be some way for all of the replacements to occur “in parallel”, so that in such a case, the final result would be ‘@@bar@@ is @@foo@@!!!’?