Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expanding variables in file contents

I have a file template.txt which contains the following:

Hello ${something}

I would like to create a PowerShell script that reads the file and expands the variables in the template, i.e.

$something = "World"
$template = Get-Content template.txt
# replace $something in template file with current value
# of variable in script -> get Hello World

How could I do this?

like image 257
Paolo Tedesco Avatar asked Nov 03 '09 12:11

Paolo Tedesco


People also ask

What is expansion variable?

Variable expansion is the term used for the ability to access and manipulate values of variables and parameters. Basic expansion is done by preceding the variable or parameter name with the $ character. This provides access to the value.

How do you expand a variable in SED?

Just use double quotes instead of single quotes. You'll also need to use {} to delimit the number_line variable correctly and escape the \ , too.

What does expansion mean in bash?

Bash uses the value formed by expanding the rest of parameter as the new parameter ; this is then expanded and that value is used in the rest of the expansion, rather than the expansion of the original parameter . This is known as indirect expansion .

Can environment variables have spaces?

Most programs separate their command line arguments with a space. But the PATH environment variable doesn't use spaces to separate directories. It uses semicolons.


2 Answers

Another option is to use ExpandString() e.g.:

$expanded = $ExecutionContext.InvokeCommand.ExpandString($template) 

Invoke-Expression will also work. However be careful. Both of these options are capable of executing arbitrary code e.g.:

# Contents of file template.txt "EvilString";$(remove-item -whatif c:\ -r -force -confirm:$false -ea 0)  $template = gc template.txt iex $template # could result in a bad day 

If you want to have a "safe" string eval without the potential to accidentally run code then you can combine PowerShell jobs and restricted runspaces to do just that e.g.:

PS> $InitSB = {$ExecutionContext.SessionState.Applications.Clear(); $ExecutionContext.SessionState.Scripts.Clear(); Get-Command | %{$_.Visibility = 'Private'}} PS> $SafeStringEvalSB = {param($str) $str} PS> $job = Start-Job -Init $InitSB -ScriptBlock $SafeStringEvalSB -ArgumentList '$foo (Notepad.exe) bar' PS> Wait-Job $job > $null PS> Receive-Job $job $foo (Notepad.exe) bar 

Now if you attempt to use an expression in the string that uses a cmdlet, this will not execute the command:

PS> $job = Start-Job -Init $InitSB -ScriptBlock $SafeStringEvalSB -ArgumentList '$foo $(Start-Process Notepad.exe) bar' PS> Wait-Job $job > $null PS> Receive-Job $job $foo $(Start-Process Notepad.exe) bar 

If you would like to see a failure if a command is attempted, then use $ExecutionContext.InvokeCommand.ExpandString to expand the $str parameter.

like image 89
Keith Hill Avatar answered Oct 20 '22 03:10

Keith Hill


I've found this solution:

$something = "World"
$template = Get-Content template.txt
$expanded = Invoke-Expression "`"$template`""
$expanded
like image 45
Paolo Tedesco Avatar answered Oct 20 '22 04:10

Paolo Tedesco