I have a file with below content, i wanted to convert all the build jobs into a different format like in expected output.
parallel
(
{
build( "job2", parameter3: value3, parameter4: value4, parameter5: value5 )
build( "job1", parameter1: value1, parameter2: value2 )
)
}
parallel
(
{
build( "job3", parameter6: value6, parameter7: value7, parameter8: value8, parameter9: value9 )
}
)
build( "jobx", parameterx: valuex, parameterx: valuex, parameterx: valuex, parameterx: valuex )
build( "jobxx", parameterxx: valuexx, parameterxx: valuexx, parameterx: valuex, parameterx: valuex )
build("jobxy", parameterxy: "https://abc-xyz.pqrs.com", parameterxy: valuexy, parameterxy: valuexy)
I am able to convert most of them with Santiago Squarzon code [link:https://stackoverflow.com/questions/76717578/loop-through-each-line-of-a-text-file-split-and-get-the-required-values-and-use#comment135289657_76717709] but not able to convert if one single job has any url in " ".
I have tried below and output is this
$teststrings = Get-Content path\to\file.txt
$re = [regex]::new(
'(?<=build\()\s*"(?<jobname>[^""]+)"(?:,\s*(?<paramname>\w+)\s*:\s*(?<paramvalue>\w+))+',
[System.Text.RegularExpressions.RegexOptions] 'Compiled, IgnoreCase')
foreach ($string in $teststrings) {
$match = $re.Match($string)
if (-not $match.Success) {
continue
}
$params = @($match.Groups['paramname'].Captures.Value)
$values = @($match.Groups['paramvalue'].Captures.Value)
$groups = for ($i = 0; $i -lt $params.Count; $i++) {
"string(name: '{0}', value: ""`${{{1}}}"")" -f $params[$i], $values[$i]
}
"build job: '{0}', parameters: [{1}]" -f $match.Groups['jobname'].Value, ($groups -join ', ')
}
Output which I got
build job: 'job2', parameters: [string(name: 'parameter3', value: "${value3}"), string(name: 'parameter4', value: "${value4}"), string(name: 'parameter5', value: "${value5}")]
build job: 'job1', parameters: [string(name: 'parameter1', value: "${value1}"), string(name: 'parameter2', value: "${value2}")]
build job: 'job3', parameters: [string(name: 'parameter6', value: "${value6}"), string(name: 'parameter7', value: "${value7}"), string(name: 'parameter8', value: "${value8}"), string(name: 'parameter9', value: "${value9}")]
build job: 'jobx', parameters: [string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}")]
build job: 'jobxx', parameters: [string(name: 'parameterxx', value: "${valuexx}"), string(name: 'parameterxx', value: "${valuexx}"), string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}")]
output for the last one was skipped.
My expected out put is
build job: 'job2', parameters: [string(name: 'parameter3', value: "${value3}"), string(name: 'parameter4', value: "${value4}"), string(name: 'parameter5', value: "${value5}")]
build job: 'job1', parameters: [string(name: 'parameter1', value: "${value1}"), string(name: 'parameter2', value: "${value2}")]
build job: 'job3', parameters: [string(name: 'parameter6', value: "${value6}"), string(name: 'parameter7', value: "${value7}"), string(name: 'parameter8', value: "${value8}"), string(name: 'parameter9', value: "${value9}")]
build job: 'jobx', parameters: [string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}")]
build job: 'jobxx', parameters: [string(name: 'parameterxx', value: "${valuexx}"), string(name: 'parameterxx', value: "${valuexx}"), string(name: 'parameterx', value: "${valuex}"), string(name: 'parameterx', value: "${valuex}")]
build job: 'jobxy', parameters: [string(name: 'parameterxy', value: "https://abc-xyz.pqrs.com"), string(name: 'parameterxy', value: "${valuexy}"), string(name: 'parameterxy', value: "${valuexy}")
Assuming the URLs are always in between "..."
then the following might work for you:
$teststrings = Get-Content path\to\file.ext
$re = [regex]::new(
'(?<=build\()\s*"(?<jobname>[^"]+)"(?:,\s*(?<paramname>\w+)\s*:\s*(?<paramvalue>\w+|".+"))+',
[System.Text.RegularExpressions.RegexOptions] 'Compiled, IgnoreCase')
foreach ($string in $teststrings) {
$match = $re.Match($string)
if (-not $match.Success) {
continue
}
$params = @($match.Groups['paramname'].Captures.Value)
$values = @($match.Groups['paramvalue'].Captures.Value)
$groups = for ($i = 0; $i -lt $params.Count; $i++) {
if ($values[$i].StartsWith('"')) {
"string(name: '{0}', value: {1})" -f $params[$i], $values[$i]
continue
}
"string(name: '{0}', value: ""`${{{1}}}"")" -f $params[$i], $values[$i]
}
"build job: '{0}', parameters: [{1}]" -f $match.Groups['jobname'].Value, ($groups -join ', ')
}
For regex details see: https://regex101.com/r/J6jDpm/1.
The only thing changing from previous code is the capturing group (?<paramvalue>\w+)
changed to (?<paramvalue>\w+|".+")
and the addition of an if
in the for
loop which checks if the captured string starts with "
and if it does then it will output it as-is (without wrapping the string in between ${...}
).