How to fetch a number from a JSON file?

2019-08-27 05:27发布

I am trying to extract the content from a JSON file to find the error description of a job only when the severity is set to 2, but I am encountered with following error message:

Error formatting a string: Input string was not in a correct format..
At line:3 char:10
+ $Sev = $("{$i`:N1}" -f $data.value.Severity)
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: ({:N1}:String) [], RuntimeException
    + FullyQualifiedErrorId : FormatError

The code which I am trying to run:

$data = Get-Content -Path 'C:\Users\S\Downloads\Logs.json' | ConvertFrom-Json 
$Sev = $("{$i`:N1}" -f $data.value.Severity)
if ($Sev -eq "2") {
    $error = $("{$i`:N1}" -f $data.value.Description)
}

Write-Host $error

JSON file content:

{
    "Id":13253665,
    "SequencerId":95521,
    "Description":"Sequence failed",
    "Severity":2,
    "SequenceStepId":null,
    "SequenceStep":null
}
{
    "Id":13253662,
    "SequencerId":95521,
    "Description":"Missing file variable.htm.",
    "Severity":4,
    "SequenceStepId":null,
    "SequenceStep":null
}

1条回答
干净又极端
2楼-- · 2019-08-27 06:06

I think you're misunderstanding how the format operator works. It expects a format string as the first operand and an array (or a single value) as the second operand.

$format_string -f $val1, $val2, $val3
$format_string -f $array
$format_string -f $single_value

A placeholder {0} in the format string refers to the first element of the second operand (array), {1} would refer to the second one, and so on. If you specify formatting instructions along with the placeholder (e.g. {0:N5} for formatting a number with a given number of digits) you also need to make sure that the value is of an appropriate type. If you want to combine a number format with a string value you need to convert the value to a number first.

PS C:\> $s = '3'
PS C:\> '{0:N5}' -f $s
3
PS C:\> '{0:N5}' -f [int]$s
3.00000

Although technically you could use a variable in format string placeholder

PS C:\> $i = 1
PS C:\> $a = 1, 3, 6
PS C:\> "{${i}:N5}" -f $a
3.00000

I would consider actually doing that bad style, as it needlessly obfuscates the code. Doing it like this is better:

PS C:\> $i = 1
PS C:\> $a = 1, 3, 6
PS C:\> '{0:N5}' -f $a[$i]
3.00000

With that said, you probably don't need any of this in the first place. For one thing, N1 in the format string would format a number 2 as a string "2.0". Comparing that to a string "2" will never find a match. Since $data.value from your JSON input seems to be an array, and the Severity values already are integers, you could simply do something like this:

if ($data.value[$i].Severity -eq 2) {
    Write-Host $data.value[$i].Description
}
查看更多
登录 后发表回答