$space =("`r`n")
$data = @(Get-Content C:\Users\user1\Desktop\ma.txt)
$Array = ($Data.Split($space)).Split($space)
$pos1 = $Array[0][0] $Array[0][1]
$pos2 = $Array[1][0] $Array[1][1]
$pos3 = $Array[2][0] $Array[2][1]
#$pos1
#$pos2
#$pos3
$zahl1 = $Array[0][5] $Array[0][7] $Array[0][9]
$zahl1
PowerShell 7.2
txt1.txt has the text:
x1 = 2 3
x2 = 8 / 4
x3 = 1 - 4
i want the results (from x1,x2,x3) to be saved at txt2.txt with a command in Terminal. I tried whith Arrays, but i only get :2 3 instead of 5
Any thoughts?
CodePudding user response:
You could use Invoke-Expression for this, but read the warning first
Get-Content -Path text1.txt | Where-Object {$_ -match '\S'} | ForEach-Object {
$var,$calculation = ($_ -split '=').Trim()
'{0} --> {1}' -f $var, (Invoke-Expression -Command $calculation)
} | Set-Content -Path text2.txt
CodePudding user response:
This is an attempt of a more secure version, that matches only mathematical expressions, so users cannot run arbitrary code through Invoke-Expression
:
Get-Content text1.txt |
Select-String '^\s*(\S )\s*=([\d\. \-*/\(\)\s] )$' |
ForEach-Object {
$var = $_.Matches.Groups[ 1 ].Value
$expression = $_.Matches.Groups[ 2 ].Value
$result = Invoke-Expression $expression
"{0} = {1}" -f $var, $result
} |
Set-Content text2.txt
The Select-String
cmdlet uses a regular expression to match only lines that are considered "safe". Within the RegEx there are two groups defined to split the line into variable (1) and calculation (2) sub strings. These are then extracted via $_.Matches.Groups
.
RegEx breakdown:
^
- line start\s*
- zero or more whitespace characters(
- start 1st capturing group\S
- one or more non-whitespace characters
)
- end 1st capturing group\s*
- zero or more whitespace characters=
- literal "="(
- start 2nd capturing group[
- start list of allowed characters\d\. \-*/\(\)\s
- digits, dot, math ops, parentheses, whitespace
]
- end the list of allowed characters
)
- end 2nd capturing group$
- line end