How to make ConvertTo-Json not remove backslashes? - json

For this JSON file:
[
{
"Wildcard": "**\\\\*.Tests*.dll"
}
]
When I use ConvertFrom-Json on this file I get this:
Wildcard : **\\*.Tests*.dll
Note that it removed two of the backslashes from the original. I want powershell to keep these backslashes, so that when I output the powershell object back to a file using ConvertTo-Json, I see the 4 backslashes in the JSON.
How can I do this?

there is a function to unescape the 4 special characters like bashslashes
ConvertTo-Json | % { [System.Text.RegularExpressions.Regex]::Unescape($_) }

Related

String Manipulation within a JSON array using jq

I am writing a bash script and I am looking to replace a character within a JSON field in a JSON array. In this case, I am trying to change the "." (period) character to a "-" (hyphen) in the name field. I am using jq to parse my JSON. Any tips on how I can achieve this will greatly help. Thank you!
Bash Script so far:
RAW=$(curl ${URL})
function manip() {
# Function for string manipulation.
}
echo "${RAW}" | jq '.data | .[].name = $manip' # Unable to make a function call in there.
Sample JSON:
[
{"id":"1","name":"a.a"},
{"id":"2","name":"b.b"},
{"id":"3","name":"c.c"}
]
Expected Output:
[
{"id":"1","name":"a-a"},
{"id":"2","name":"b-b"},
{"id":"3","name":"c-c"}
]
To replace a dot with a dash, use the sub function:
jq '.[].name |= sub("\\."; "-")' file.json

How to prettify json with jq given a string with escaped double quotes

I would like to pretty print a json string I copied from an API call which contains escaped double quotes.
Similar to this:
"{\"name\":\"Hans\", \"Hobbies\":[\"Car\",\"Swimming\"]}"
However when I execute pbpaste | jq "." the result is not changed and is still in one line.
I guess the problem are the escaped double quotes, but I don't know how to tell jq to remove them if possible, or any other workaround.
What you have is a JSON string which happens to contain a JSON object. You can decode the contents of the string with the fromjson function.
$ pbpaste | jq "."
"{\"name\":\"Hans\", \"Hobbies\":[\"Car\",\"Swimming\"]}"
$ pbpaste | jq "fromjson"
{
"name": "Hans",
"Hobbies": [
"Car",
"Swimming"
]
}

Using Powershell to convert a file's contents into a string that can be transferred using JSON

How does one convert a text file's contents into a string and then insert this string into a JSON file?
For example, if a file contains:
this
is
a
sample
file
The script would generate:
"this\r\nis\r\na\r\nsample\r\nfile"
To insert into a JSON template:
"something":"<insertPoint>"
To produce:
"something":"this\r\nis\r\na\r\nsample\r\nfile"
I'm using Powershell 5 and have managed to load the file, generate some JSON and insert it by running:
# get contents and convert to JSON
$contentToInsert = Get-Content $sourceFilePath -raw | ConvertTo-Json
# write in output file
(Get-Content $outputFile -Raw).replace('<insertPoint>', $contentToInsert) | Set-Content $outputFile
However, a lot of other, unwanted fields are also added.
"something":"{
"value": "this\r\nis\r\na\r\nsample\r\nfile"
"PSPath": "C:\\src\\intro.md",
"PSParentPath": "C:\\src",
"PSChildName": "intro.md",
etc...
Ultimately, I'm trying to send small rich text segments to a web page via JSON but want to edit and store them locally using Markdown. If this doesn't make sense and there's a better way of sending these then please let me know also.
iRon's answer helpfully suggests not using string manipulation to create JSON in PowerShell, but to use hashtables (or custom objects) to construct the data and then convert it to JSON.
However, that alone does not solve your problem:
PS> #{ something = Get-Content -Raw $sourceFilePath } | ConvertTo-Json
{
"something": {
"value": "this\nis\na\nsample\nfile\n",
"PSPath": "/Users/mklement/Desktop/pg/lines.txt",
# ... !! unwanted properties are still there
}
The root cause of the problem is that Get-Content decorates the strings it outputs with metadata in the form of NoteProperty properties, and ConvertTo-Json currently invariably includes these.
A proposal to allow opting out of this decoration when calling Get-Content can be found in GitHub issue #7537.
Complementarily, GitHub issue #5797 suggests that ConvertTo-Json should ignore the extra properties for primitive .NET types such as strings.
The simplest workaround is to access the underlying .NET instance with .psobject.baseobject, which bypasses the invisible wrapper object PowerShell uses to supply the extra properties:
PS> #{ something = (Get-Content -Raw $sourceFilePath).psobject.baseobject } |
ConvertTo-Json
{
"something": "this\nis\na\nsample\nfile\n"
}
Just a general recommendation apart from the actually issue described by #mklement0 and metadata added to the Get-Content results:
Do not poke (replace, insert, etc.) in any Json content.
Instead, modify the object (if necessary, use ConvertFrom-Json to restore the object) prior converting it into (ConvertTo-Json) a Json file.
In this example, I would use a hash-table with a here-string for this:
#{'something' = #'
this
is
a
sample
file
'#
} | ConvertTo-Json
Result:
{
"something": "this\nis\na\nsample\nfile"
}
You can use the Out-String cmdlet to coerce the output of Get-Content into a flat string first:
#{ "something" = (Get-Content lines.txt | Out-String) } | ConvertTo-Json
This produces:
{
"something": "this\r\nis\r\na\r\nsample\r\nfile\r\n"
}

Minify JSON with PowerShell?

Is there a way to minify (remove all whitespace in this case) a JSON file to turn this
[
0.000005,
0,
0
],
[
219.740502,
0.003449,
4.177065
],
[
45.210918,
0.003365,
-16.008996
],
[
344.552785,
0.030213,
277.614965
],
to this using PowerShell
[0.000005,0,0],[219.740502,0.003449,4.177065],[45.210918,0.003365,-16.008996],[344.552785,0.030213,277.614965],
I have tried several online "minifiers" however the file contains over 100,000 arrays and basically broke all the online minifiers. Any ideas?
Just for your information when you manipulate PowerShell object and convert them to JSON (ConvertTo-Json) you've got the -compress param :
New-Object -TypeName PSCustomObject -Property #{Name="Hugot";GivenName="Victor"} | ConvertTo-Json -Compress
gives :
{"GivenName":"Victor","Name":"Hugot"}
Adding to JP's answer,
(ConvertFrom-Json $json) | ConvertTo-Json -Compress
This is useful if you already have json. If you don't do the ConvertFrom-Json on the front, then it will encode the line breaks with \r\n and the quotes with \".
You can easily do so with a basic regex. If you have this in a file try the following. You must include the -Raw parameter or the file will be passed one line at a time which will prevent the regex from removing the newline character.
(Get-Content C:\Some\File.json -Raw) -replace '\s','' | out-file C:\some\outfile.json

"Invalid JSON primitive" error when converting JSON file

When trying to convert a JSON file via PowerShell:
$json = Get-Content "C:\folder1\test.txt"
$json | ConvertFrom-Json
write-output $json
I'm getting the following error:
invalid json primitive : [.
(system.argunment.exception)
I'm going out on a limb here, since you didn't provide your input data or the complete error message, but I guess that your problem is caused by a format mismatch between the output Get-Content provides and the input ConvertFrom-Json expects.
Get-Content reads the input file into an array of strings, whereas ConvertFrom-Json expects the JSON data in a single string. Also, piping $json into ConvertFrom-Json does not change the value of $json.
Change your code to the following and the error should disapear (provided there is no syntactical error in your input data):
$json = Get-Content 'C:\folder1\test.txt' | Out-String | ConvertFrom-Json
Write-Output $json
You should check your JSON input file for characters that are not properly escaped with a "\"
I have also seen this issue with an input JSON file that was incorrectly formatted as follows:
{
Object1
}
{
Object2
}
Corrected format:
[{
Object1
},
{
Object2
}]
Once the format was corrected, I had no more issues.
I was also receiving this error, and upon investigating my json file noticed that some of the JSON was invalid. I was ending the last object in an array with a comma like so:
[{ ..},]
Removing the comma fixed the issue for myself.
So in short, invalid JSON caused this issue for me.
You will get this error if your input data starts like this:
data: [
{
...
},
{
...
}
]
You need to remove data: (and only have [and ] in this example):
[
{
...
},
{
...
}
]