1

I have a json data like this.

sample.json

[
  {
    "id": 0,
    "name": "Cofine",
    "title": "laboris minim qui nisi esse amet non",
    "description": "Consequat laborum quis exercitation culpa. Culpa esse sint consectetur deserunt non.",
    "website": "cofine.com",
    "image": "http://placehold.it/32x32",
    "labels": ["blue", "red"],
    "labels_link": ["http://cofine.com/labels/blue","http://cofine.com/labels/red"],
  },
  {
    "id": 1,
    "name": "Zomboid",
    "title": "adipisicing mollit esse aliquip ullamco nisi laboris",
    "description": "Enim consectetur eu commodo officia. Id pariatur proident nostrud occaecat adipisicing voluptate do nisi incididunt id ex commodo.",
    "website": "zomboid.com",
    "image": "http://placehold.it/32x32",
    "labels": ["red"],
    "labels_link": ["http://zomboid.com/labels/red"],
  },
  {
    "id": 2,
    "name": "Sulfax",
    "title": "non minim anim irure nulla ad elit",
    "description": "Pariatur anim officia adipisicing Lorem dolor cillum eu ex veniam sint consequat incididunt. Minim mollit reprehenderit mollit sint laboris consequat.",
    "website": "sulfax.com",
    "image": "http://placehold.it/32x32",
    "labels": ["green", "yellow", "blue"],
    "labels_link": ["http://sulfax.com/labels/green","http://sulfax.com/labels/yellow","http://sulfax.com/labels/blue"],
  }
]

How do I convert this json data to yaml using PowerShell where each json object will be converted to yaml and saved as yaml in its own file with the file name being the value of the title keys properties?

When I run the following command ($json | ConvertFrom-Json) | ConvertTo-YAML (where the ConvertTo-YAML function is taken from the simpletalk website), this is the output I get.

Output

---

 id: 0 
 name: 'Cofine' 
 title: 'laboris minim qui nisi esse amet non' 
 description:     Consequat laborum quis exercitation culpa. Culpa esse sint consectetur deserunt     non. 
 website: 'cofine.com' 
 image: 'http://placehold.it/32x32' 
 labels: 
    - 'blue' 
    - 'red' 
 labels_link: 
    - 'http://cofine.com/labels/blue' 
    - 'http://cofine.com/labels/red'
---

 id: 1 
 name: 'Zomboid' 
 title: 'adipisicing mollit esse aliquip ullamco nisi laboris' 
 description:     Enim consectetur eu commodo officia. Id pariatur proident nostrud occaecat adipisicing     voluptate do nisi incididunt id ex commodo. 
 website: 'zomboid.com' 
 image: 'http://placehold.it/32x32' 
 labels: 
    - 'red' 
 labels_link: 
    - 'http://zomboid.com/labels/red'
---

 id: 2 
 name: 'Sulfax' 
 title: 'non minim anim irure nulla ad elit' 
 description:     Pariatur anim officia adipisicing Lorem dolor cillum eu ex veniam sint consequat     incididunt. Minim mollit reprehenderit mollit sint laboris consequat. 
 website: 'sulfax.com' 
 image: 'http://placehold.it/32x32' 
 labels: 
    - 'green' 
    - 'yellow' 
    - 'blue' 
 labels_link: 
    - 'http://sulfax.com/labels/green' 
    - 'http://sulfax.com/labels/yellow' 
    - 'http://sulfax.com/labels/blue'

However, the output I am looking for would look like this - where the filename is the value of the title keys properties and the content of the file would be the corresponding json object converted to yaml.

laboris minim qui nisi esse amet non.yaml

---
 id: 0 
 name: 'Cofine' 
 title: 'laboris minim qui nisi esse amet non' 
 description: Consequat laborum quis exercitation culpa. Culpa esse sint consectetur deserunt non.
 website: 'cofine.com' 
 image: 'http://placehold.it/32x32' 
 labels: 
    - 'blue' 
    - 'red' 
 labels_link: 
    - 'http://cofine.com/labels/blue' 
    - 'http://cofine.com/labels/red'
---

adipisicing mollit esse aliquip ullamco nisi laboris.yaml

---
 id: 1 
 name: 'Zomboid' 
 title: 'adipisicing mollit esse aliquip ullamco nisi laboris' 
 description: Enim consectetur eu commodo officia. Id pariatur proident nostrud occaecat adipisicing voluptate do nisi incididunt id ex commodo.
 website: 'zomboid.com' 
 image: 'http://placehold.it/32x32' 
 labels: 
    - 'red' 
 labels_link: 
    - 'http://zomboid.com/labels/red'
---

non minim anim irure nulla ad elit.yaml

---
 id: 2 
 name: 'Sulfax' 
 title: 'non minim anim irure nulla ad elit' 
 description: Pariatur anim officia adipisicing Lorem dolor cillum eu ex veniam sint consequat incididunt. Minim mollit reprehenderit mollit sint laboris consequat.
 website: 'sulfax.com' 
 image: 'http://placehold.it/32x32' 
 labels: 
    - 'green' 
    - 'yellow' 
    - 'blue' 
 labels_link: 
    - 'http://sulfax.com/labels/green' 
    - 'http://sulfax.com/labels/yellow' 
    - 'http://sulfax.com/labels/blue'
---
Ishan
  • 3,370
  • 6
  • 29
  • 32
  • Have you read this? https://www.simple-talk.com/sysadmin/powershell/getting-data-into-and-out-of-powershell-objects/ – SadBunny Aug 25 '16 at 00:41
  • @SadBunny yeah, I have – Ishan Aug 25 '16 at 00:43
  • It seems like that has a full implementation for your exact purpose. No? – SadBunny Aug 25 '16 at 23:01
  • @SadBunny, No that article does not do exactly what I want. See my updated question. – Ishan Aug 26 '16 at 00:13
  • Well, that is certainly a very specific function... So, you want to split the incoming data out into one or more files where the filename depends on the value of a specific key? That would mean that you have to adapt your current code to do just that. If you don't know how, it's probably a good idea to post your code to stack overflow and ask for help changing the code to your functionality. It's probably not that hard, you'd have to split the YAML objects, loop through them, get the value and then save that thing. A possible shortcut is a massive regex search-and-replace on the total result. – SadBunny Aug 26 '16 at 00:31
  • By the way, you shouldn't begin AND end your yaml with "---", yaml only *begins* with "---". The next "---" is the start of the next block. – SadBunny Aug 26 '16 at 01:12
  • I'm a linux guy, so here's an example, if you'd pipe that yaml through the following gawk script it does what you want :) Don't know if it's of any use, but I tested it and it works: moo@monsterkill:/tmp$ cat test.txt | gawk -f test.gawk Wrote file: laboris minim qui nisi esse amet non Wrote file: adipisicing mollit esse aliquip ullamco nisi laboris Wrote file: non minim anim irure nulla ad elit – SadBunny Aug 26 '16 at 01:21
  • BEGIN{filename=""} { if ($0=="---") { writeTheFile(); content=""; } content = content "" $0 "\n"; if ($0 ~ "title: ") { filename=substr($0, index($0, "'") + 1) filename=substr(filename, 1, index(filename, "'") - 1) } } END{writeTheFile();} function writeTheFile() { if (filename=="") {return;} else { print content > filename; close(filename); print("Wrote file: " filename); } } – SadBunny Aug 26 '16 at 01:21
  • Sorry, imagine your own newlines as SU has killed them :/ – SadBunny Aug 26 '16 at 01:21
  • Could you please include your gawk script on github gist. It is very difficult to read at the moment. – Ishan Aug 26 '16 at 02:03
  • Sure, here you go: https://gist.github.com/SadBunny/a2d0f5421eb660096896f22cbbc46e4a – SadBunny Aug 26 '16 at 19:06
  • @SadBunny, When I run your script on git bash on windows, it just creates a `non minim anim irure nulla ad elit.yaml` file with the whole data in yaml format as its content which is not what I am after. However running the same script on linux does exactly what you said. – Ishan Aug 29 '16 at 00:09
  • Probably a newline issue. – SadBunny Aug 29 '16 at 04:51

1 Answers1

3

I'm answering my own question in case someone else is looking for an answer.

$obj = ($json  | ConvertFrom-Json)

ForEach($item in $obj) {
    $filename = "$($item.title).yaml"
    $item | ConvertTo-YAML > $filename
    "---" >> $filename
}
Ishan
  • 3,370
  • 6
  • 29
  • 32