3

I’m using jq to manipulate a JSON file. I need to run a single command that searches an array, finds an object that has a key that equals “someData”, and then delete a key that is in the object, for example, delete a “maxHeight” key from the object where key equals “someData”. Here is an example JSON file, I would like to search the ‘tracks’ array and find the object where label =“cucumber_ChineseLong_v2.gff3” and then remove the ‘maxHeight: “200px” ‘ from that object. Is this even possible to run in a single command using jq?

Update: My desired output would be the original JSON file with that 'maxHeight' key:value removed.

Update: A few commands I've tried..

jq '. as $dot|[range(0;length)|select(.maxHeight == "200px")|$dot[.]]' trackList.json > new.json

jq '.tracks[]  | select(.label == "cucumber_ChineseLong_v2.gff3")' trackList.json > test.json
  • The Last command can isolate the correct Array, Now I need to know how to delete a key from a object using jq.

JSON File

{
  "tracks": [
    {
      "storeClass": "JBrowse/Store/Sequence/StaticChunked",
      "chunkSize": 20000,
      "urlTemplate": "seq/{refseq_dirpath}/{refseq}-",
      "label": "DNA",
      "type": "SequenceTrack",
      "category": "Reference sequence",
      "seqType": "dna",
      "key": "Reference sequence"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "CG0001.gff",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/CG0001.gff/{refseq}/trackData.json",
      "compress": 0,
      "label": "CG0001.gff",
      "type": "FeatureTrack"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "CG0002.gff",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/CG0002.gff/{refseq}/trackData.json",
      "compress": 0,
      "label": "CG0002.gff",
      "type": "FeatureTrack"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "CG0003.gff",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/CG0003.gff/{refseq}/trackData.json",
      "compress": 0,
      "label": "CG0003.gff",
      "type": "FeatureTrack"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "CG0004.gff",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/CG0004.gff/{refseq}/trackData.json",
      "compress": 0,
      "label": "CG0004.gff",
      "type": "FeatureTrack"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "CG0005.gff",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/CG0005.gff/{refseq}/trackData.json",
      "compress": 0,
      "label": "CG0005.gff",
      "type": "FeatureTrack"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "CG0010.gff",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/CG0010.gff/{refseq}/trackData.json",
      "compress": 0,
      "label": "CG0010.gff",
      "type": "FeatureTrack"
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "color": "function(feature, variableName, glyphObject, track){if(feature.get(\"type\") === \"CDS\"){return \"#9CFBF5\";} else if(feature.get(\"type\") === \"exon\"){return \"#43A47F\";} else if(feature.get(\"type\") === \"intron\"){return \"#E8E8E8\";} else if(feature.get(\"type\") === \"five_prime_UTR\"){return \"#F192FE\";} else if(feature.get(\"type\") === \"three_prime_UTR\"){return \"#FEC892\";} else {return \"#FF0000\";}}",
        "arrowheadClass": null,
        "featureCss": "padding:3px;"
      },
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Highlight a gene"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( feature[2] ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ],
      "hooks": {
        "modify": " function(track,feature,div){   var checkArr=[\"Reference\",\"Missing\",\"Heterozygous\",\"NonReference\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"NonReference\"){div.style.backgroundColor=\"red\"}else if(feature[i]==\"Reference\"){div.style.backgroundColor=\"green\"}else if(feature[i]==\"Heterozygous\"){div.style.backgroundColor=\"orange\"}else if(feature[i]==\"Missing\"){div.style.backgroundColor=\"grey\"} }}}}} "
      },
      "key": "cucumber_ChineseLong_v2.gff3",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/cucumber_ChineseLong_v2.gff3/{refseq}/trackData.json",
      "compress": 0,
      "label": "cucumber_ChineseLong_v2.gff3",
      "type": "JBrowse/View/Track/CanvasFeatures"
    },
    {
      "storeClass": "JBrowse/Store/SeqFeature/VCFTabix",
      "urlTemplate": "Cucumber115_chronly.vcf.gz",
      "maxHeight": "200px",
      "type": "CanvasVariants",
      "label": "Cucumber115_chronly.vcf",
      "menuTemplate": [
        {
          "label": "View details"
        },
        {
          "label": "Zoom"
        },
        {
          "iconClass": "dijitIconFilter",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().selectSequence( div.f.data.end ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Select Sequence"
        },
        {
          "iconClass": "dijitIconBookmark",
          "content": "function(track,feature,div) { window.parent.angular.element(window.frameElement).scope().specificNote( div.f.data.end ) }",
          "action": "contentDialog",
          "title": "(feature{name})",
          "label": "Create Note"
        }
      ]
    },
    {
      "style": {
        "className": "feature",
        "showLabels": false,
        "arrowheadClass": null,
        "featureCss": "padding:7px;"
      },
      "hooks": {
        "modify": " function(track,feature,div){ var checkArr=[\"Gene\",\"Variant\",\"Primer\"];for(var i=0;i<feature.length;i++){for(var j=0;j<checkArr.length;j++){  if( i>3) { if( feature[i] ===  checkArr[j] ) {  if(feature[i]==\"Gene\"){div.style.backgroundColor=\"pink\"}else if(feature[i]==\"Variant\"){div.style.backgroundColor=\"purple\"}else if(feature[i]==\"Primer\"){div.style.backgroundColor=\"blue\"} }}}}} "
      },
      "key": "Notes",
      "storeClass": "JBrowse/Store/SeqFeature/NCList",
      "trackType": null,
      "maxHeight": "200px",
      "urlTemplate": "tracks/Notes/{refseq}/trackData.json",
      "compress": 0,
      "type": "FeatureTrack",
      "label": "Notes"
    }
  ],
  "formatVersion": 1
}
Edric
  • 24,639
  • 13
  • 81
  • 91
MostlyRquestions
  • 526
  • 2
  • 7
  • 22
  • why shouldn't it be possible? what have you tried so far? – snap Jan 30 '18 at 16:52
  • I'm new working with jq, if it's possible can you show me an example? – MostlyRquestions Jan 30 '18 at 17:04
  • I don't have much experience with jq but from what I have see I would expect that your requirement is feasible. here is a good starting point to get familiar with it and find it out: https://stedolan.github.io/jq/tutorial/ – snap Jan 30 '18 at 17:08
  • Yes, I started there, and this also helped, https://github.com/stedolan/jq/issues/323, but I'm still struggling with this command. – MostlyRquestions Jan 30 '18 at 17:14

1 Answers1

6

Unfortunately you have not followed the guidelines at http://stackoverflow.com/help/mcve so it is difficult to tell from your description what output you are expecting, but the simplest way to delete a key from an object is to use del/1 as in the following:

.tracks
| map(select(.label=="cucumber_ChineseLong_v2.gff3") 
      | del(.maxHeight))

With your JSON as input, the result of the above query is rather long, so I won't include it in this response -- the "m" in "mcve" stands for "minimal".

Supplementary Q&A

Is it possible to return the original file with the 'maxHeight' removed?

For "editing" (as opposed to extraction), the trick is to use |=. There are many variations possible, for example:

.tracks |=
  map(if .label=="cucumber_ChineseLong_v2.gff3"
      then del(.maxHeight)
      else .
      end)

Some prefer the one-liner:

.tracks[] |= if .label=="cucumber_ChineseLong_v2.gff3" then del(.maxHeight) else . end
peak
  • 105,803
  • 17
  • 152
  • 177
  • sorry I didn't properly define my desired output, I'm looking to output the same file, except I want to remove the 'maxHeight' variable from that specific array. Your code above is great but only outputs that array. Is it possible to return the original file with the 'maxHeight' removed? Thanks! – MostlyRquestions Jan 30 '18 at 19:32
  • Excellent! Thank you – MostlyRquestions Jan 30 '18 at 19:46