Extract a variable from a bunch of files

I have a couple of TXT files. They contain some text, along with a line like this:

The version number keeps changing.

I want to list all these files along with the value of $version in that file. Here’s how:

The result is something like this:

It’s pretty straight-forward what I am doing. I use Get-Item to get all the TXT files. Pipe it to a ForEach-Object loop. Within that I use the Get-Content cmdlet to get the contents of the file. I could have stored the contents in a variable and then done the remaining bits, instead I send it directly to the -match operator to get out lines that contain the pattern I am looking for. After this I replace the line to extract the numbers between double-quotes and store that in a variable. Finally I output the file name and the version (only if a version was found).

The two patterns pattern took me a while to figure out so I’ll delve a bit more into it here. I use a similar pattern for the -match and -replace operators so my comments here apply to both. The patterns are pretty straight-forward but for the fact that I need to match symbols such as dollar ($) and double-quotes (“). That in itself is not a hassle as I can escape them and match as $ or ” but that didn’t work in my case. I kept getting errors like this:

Why does this happen? Thanks to a Stack Overflow post I got the answer. What happens is that although I escape the $ as $ within the regular expression, since $ is a special character for PowerShell (variable names) it clubs the $ with the word “version” and treats it as a variable $version. And since this variable isn’t defined, it expands to an empty string which PowerShell passes to the -match operator as the pattern “^”. This pattern doesn’t make sense and so we get the error above.

Workaround is to double escape the $ symbol. As `$. If we do that I get the following error:

Not sure why I get an error here. The period character is an operator in PowerShell, and since the error points to that something roundabouts the period operator is confusing PowerShell. Ideally the whole pattern ^`$version = ".*" should be passed to the -match operator, but PowerShell only seems to be passing ^`$version = and using the period as a deference operator to that string. Which of course will not work because the left hand side is a string and not an object, but also because the right hand side *"$" is not a property name. So again it looks to be similar to the earlier error. The double quotes are being usurped by PowerShell first, before passing to the -match operator, and so they too need to be double escaped.

Hence I use the pattern ^`$version.* for the -match operator and the pattern ^`$version = `"(.+)`"$ for the -replace operator. Double-escaping the $ and ” characters.