Giter Club home page Giter Club logo

jsawk's Introduction

Quick Start

If you use Jsawk and want to help maintain it, please let me know and I'll add you to the repo.

Updated underscore.js to v1.8.2.

Jsawk is like awk, but for JSON. You work with an array of JSON objects read from stdin, filter them using JavaScript to produce a results array that is printed to stdout. You can use this as a filter to manipulate data from a REST JSON web service, for example, in a shell script. Also, you can suppress JSON output and use the built-in printing functions to translate your JSON input to other formats and send that to stdout, to be piped to other processes. You can load JavaScript libraries on the command line to increase your processing power, and other things.

Setup

This is a great blog post on setup and basic use of jsawk and resty, thanks to @johnattebury.

You need to have the js interpreter installed. Your best bet is to navigate to the mozilla site download and build the source based on the maintained documentation there.

Ready? Go.

Install

First, get the jsawk script:

  curl -L http://github.com/micha/jsawk/raw/master/jsawk > jsawk

Then make it executable and put it somewhere in your path:

  chmod 755 jsawk && mv jsawk ~/bin/

Use

Now you can do some stuff with JSON data. Here's an example using data from a REST service that serves JSON (we use resty to do the HTTP requests):

  resty http://example.com:8080/data*.json
  GET /people/47 | jsawk 'this.favoriteColor = "blue"' | PUT /people/47

This would do a GET request on the resource /data/people/47.json, which would result in a JSON object. Then jsawk takes the JSON via stdin and for each JSON object it runs the little snippet of JavaScript, setting the favoriteColor property to "blue", in this case. The modified JSON is then output via stdout to resty again, which does the PUT request to update the resource.

Usage

  jsawk [OPTIONS] [SCRIPT]

  OPTIONS
  -------

  -b <script> | -a <script>
      Run the specified snippet of JavaScript before (-b) or after (-a)
      processing JSON input. The `this` object is set to the whole JSON
      array or object. This is used to preprocess (-b) or postprocess
      (-a) the JSON array before or after the main script is applied.
      This option can be specified multiple times to define multiple
      before/after scripts, which will be applied in the order they
      appeared on the command line.

  -f <file>
      Load and run the specified JavaScript file prior to processing
      JSON. This option can be specified multiple times to load multiple
      JavaScript libraries.

  -h
      Print short help page and exit.

  -i <file>
      Read input JSON from `file` instead of stdin.

  -j <jsbin>
      Specify path to spidermonkey js binary.

  -n
      Suppress printing of JSON result set.

  -q <query>
      Filter JSON through the specified JSONQuery query. If multiple
      '-q' options are specified then each query will be performed in
      turn, in the order in which they appeared on the command line.

  -s <string>
      Use `string` for input JSON instead of stdin.

  -v <name=value>
      Set global variable `name` to `value` in the script environment.

  SCRIPT
  ------

  This is a snippet of JavaScript that will be run on each element
  of the input array, if input is a JSON array, or on the object if
  it's an object. For each iteration, the `this` object is set to the
  current element.

Using A Specific JS Binary

The path to the js binary can be specified in two different ways:

  • the -j command line option (see above)
  • the JS environment variable

Additionally, jsawk will source the following files at startup if they exist:

  • /etc/jsawkrc
  • ~/.jsawkrc

These files can be used to export the JS environment variable.

Jsawk Scripting

Jsawk is intended to serve the purpose that is served by awk in the shell environment, but instead of working with words and lines of text, it works with JavaScript objects and arrays of objects.

In awk, a text file is split into an array of "records", each of which being an array of "fields". The awk script that is specified on the command line is run once for each record in the array, with the $1, $2, etc. variables set to the various fields in the record. The awk script can set variables, perform calculations, do various text-munging things, and print output. This printing capablity makes awk into a filter, taking text input, transforming it record by record, printing out the resulting modified records at the end.

Jsawk is similar, but in jsawk records are elements of the JSON input array (if the input was a single object then there is a single record consisting of that object). The jsawk script is run once for each record object, with the this object set to the current record. So here the properties of the record object are equivalent to the $1, $2, etc. in awk. The jsawk script can then modify the record, perform calculations, do things. However, instead of printing the modified record, the modified record is returned. At then end, if the -n option was not specified, the resulting array is printed as JSON to stdout.

Jsawk JavaScript Environment

Jsawk uses the Spidermonkey JavaScript interpreter, so you have access to all of the Spidermonkey functions and whatnot. Additionally, the following functions and properties are available from within a jsawk script:

  PROPERTIES
  ----------

    window
        The global object.

    IS
        The input set.

    RS
        The result set.

    _   The underscore.js object.

    $_
        The current record index (corresponding to the index of the
        element in the IS array).

    $$
        The current record object (global variable corresponding to the
        `this` object in the script scope).

  METHODS
  -------

    forEach(array, string)
        Compiles 'string' into a function and iterates over the 'array',
        running the function once for each element. The function has
        access to the special variables 'index' and 'item' which are,
        respectively, the array index and the array element. The 'this'
        object is set to the array element each time the function runs.

        params: Array array (array to iterate over)
                String string (the function source)
        return: void

    get()
        Get the next record from the input set. This will prevent jsawk
        from iterating over that record.

        params: void
        return: Object|Array|Number|String (the next input record)

    put(record)
        Push 'record' onto the input set so that jsawk will iterate over
        it next.

        params: Object|Array|Number|String record (the record to push)
        return: void

    json(thing)
        Serialize 'thing' to JSON string.

        params: Object|Array|Number|String thing (what to serialize)
        return: String (the resulting JSON string)

    uniq(array)
        Return array of distinct elements.

        params: Array array (the input array)
        return: Array (the resulting array of distinct elements)

    Q(query, thing)
        Runs the JSONQuery 'query' on the JSON input 'thing'.

        params: String query (the JSONQuery)
                Array|Object thing (the JSON input)
        return: Array|Object (result of running the query)

    err(thing)
        Print arguments (JSON encoded, if necessary) to stderr.

        params: Object|Array|Number|String thing (what to encode)
        return: void

    out(thing)
        Print arguments (JSON encoded, if necessary) to stdout.

        params: Object|Array|Number|String thing (what to encode)
        return: void

Errors and Output

Errors in parsing scripts, JSON queries, or JSON input, and errors executing scripts will all result in the appropriate error message on stderr, and immediate exit with a non-zero exit status. Normal output is written to stdout, unless the -n option is specified. In that case only output from the out() or err() functions and error messages will appear.

Exit Status

On successful completion jsawk returns an exit status of 0. If an error ocurred and execution was aborted, a non-zero exit status will be returned.

Exit Status

  • 0 Successful completion.
  • 1 Command line parsing error.
  • 2 JSON parsing error.
  • 3 Script error.
  • 4 JSONQuery parsing error.
  • 5 JSON stringify error.

JSONQuery

Jsawk supports JSONQuery with the -q option. You can do almost anything with JSONQuery that you can do with jsawk scripts, to include selecting records, drilling down into records, mapping input sets to output sets as a sort of filter, modifying the JSON, sorting, whathaveyou. JSONQuery is to JSONPath is to JSON, as XQuery is to XPath is to XML. Here are some JSONQuery resources to get started with this powerful tool:

Examples

For the following examples, suppose there is a file /tmp/t, with the following contents:

  [
    {
      "first"   : "trevor",
      "last"    : "wellington",
      "from"    : "england",
      "age"     : 52,
      "sports"  : [ "rugby", "badmitton", "snooker" ]
    },
    {
      "first"   : "yoni",
      "last"    : "halevi",
      "from"    : "israel",
      "age"     : 26,
      "sports"  : [ "soccer", "windsurfing" ]
    },
    {
      "first"   : "cory",
      "last"    : "parker",
      "from"    : "united states",
      "age"     : 31,
      "sports"  : [ "windsurfing", "baseball", "extreeeeme kayaking" ]
    }
  ]

This is going to be the input JSON text we will use in the examples.

JSON-to-JSON Transformations

These examples transform the input JSON, modifying it and returning the modified JSON as output on stdout to be piped elsewhere. Transformations of this type are generally done with a script that follows one of these simple patterns:

  1. Modify the this object in place (no return statement necessary).
  2. Create a replacement object for each record, and return it at the end of each iteration.

These patterns leave the records in JSON format, and they are automatically printed to stdout without the use of the out() function.

The Identity Mapping

This is the identity transformation: it doesn't really do anything other than pass the input straight through.

  cat /tmp/t | jsawk

You should get the input back out, unmolested.

Increment Everyone's Age

Looks like it's everyone's birthday today. We'll take the JSON input and increment each object's age property, sending the resulting JSON output to stdout.

  cat /tmp/t | jsawk 'this.age++'

Notice that there is no need to write return this in the script. That is assumed---the runtime does it for you automatically if you don't explicitly call return yourself.

Flatten The "Sports" Array Of Each Element

Here we modify the input by replacing the sports property of each object in the input array (the sports property is itself an array of strings) with a single string containing all of the person's sports, separated by commas.

  cat /tmp/t | jsawk 'this.sports = this.sports.join(",")'

Notice how altering the this object in place alters the result array accordingly.

Extract Only The "Age" Property Of Each Element

Normally we would modify the input set in place, by manipulating the this object, which would be returned by default after each iteration. However, sometimes we want only a single field from the input set.

  cat /tmp/t | jsawk 'return this.age'

Putting a return statement in the script expression causes the default return of this to be short-circuited, replacing this element with the return value in the output set.

JSON Grep: Select Certain Elements From Input

Sometimes you want to use awk to select certain records from the input set, leaving the rest unchanged. This is like the grep pattern of operation. In this example we will extract all the records corresponding to people who are over 30 years old.

  cat /tmp/t | jsawk 'if (this.age <= 30) return null'

This demonstrates how you can remove records from the results array by returning a null value from your script.

Aggregate Functions

Before and after scripts can be used to manipulate the JSON working set as a whole, somewhat similar to the way aggregate functions like SUM() or COUNT() work in SQL. These types of operations fall under a few basic patterns.

  1. Use a before script (-b option) to do things to the JSON input before transformations are done by the main script.
  2. Use an after script (-a option) to do things to the JSON result set after all transformations are completed by the main script.

Count How Many Elements Are In The Input Array

Here we use an after script to modify the result set, like this:

  cat /tmp/t | jsawk -a 'return this.length'

Notice how the entire results array is replaced by the single number and printed to stdout.

Get a Sorted, Unique List of All Sports

This is an example of a JSON-to-JSON transformation that uses an after script to manipulate the result set. It should produce an array of all sports played by the people in the input set, sorted lexically, and with all duplicate elements removed.

  cat /tmp/t \
    | jsawk 'RS=RS.concat(this.sports); return null' -a 'return uniq(RS).sort()'

Note the use of return null to prevent jsawk from adding the this object to the result set automatically. Instead we manipulated the result set explicitly, enabling each iteration to add more that one element to it---the entire sports array. Also, notice the use of an after script to sort the result set and remove duplicates.

JSON-to-Text Transformations

In the following examples we will be manipulating the JSON input to produce text output instead of JSON, for cases where you will be extracting information from a JSON data source and piping it to non JSON-accepting processes elsewhere.

It is frequently useful to supress the regular JSON output when doing JSON-to-Text transformations like these, with the -n option.

Get A List Of All Sports

This one generates a list of all the sports that are played by the people in our little JSON list, one per line, without duplicate entries, sorted alphabetically.

  cat /tmp/t \
    | jsawk -a 'return this.join("\n")' 'return this.sports.join("\n")' \
    | sort -u

Notice the use of JSONQuery to drill down into the JSON objects, an "after" script to collate the results, and everything piped to the Unix sort tool to remove duplicate entries and do the lexical ordering. This is starting to show the power of the awk-like behavior now.

Return a Boolean Value

Sometimes you want to just check for a certain condition in a shell script. Suppose you want to know if there are any people over the age of 50 in the JSON input array, like this:

  jsawk -n 'if (this.age > 50) quit(1)' < /tmp/t || echo "We have people over 50 here---naptime in effect."

We suppress normal result set output with -n and use the quit() function to return a value in the exit status. The default exit status is, of course, zero for success.

JSON Pretty-Printing

Resty includes the pp script that will pretty-print JSON for you. You just need to install the JSON perl module from CPAN. Use it like this:

  GET /blogs.json | jsawk -q '..author' | pp

jsawk's People

Contributors

dansoton avatar flamusdiu avatar micha avatar peritus avatar rjp avatar zardam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsawk's Issues

Output object values as text

I have a json object like this:
[{
"id":1,
"layout":
{"indexes":
{"positions":
[{"column":3,"row":2},
{"column:5,"row":4},
{"column":7,"row":1}]}}}]

And I want to output text like this where the columns are id, column, row:
1, 3, 2
1, 5, 4
1, 7, 1

I'm stuck - any ideas?

doJson is not defined

When I use this command

cat /tmp/t | jsawk

I get this error

/tmp/tmp.kwytkE:1049
  IS      = doJson(input);
            ^
ReferenceError: doJson is not defined
    at /tmp/tmp.kwytkE:1049:13
    at Object.<anonymous> (/tmp/tmp.kwytkE:1088:3)
    at Module._compile (module.js:446:26)
    at Object..js (module.js:464:10)
    at Module.load (module.js:353:32)
    at Function._load (module.js:311:12)
    at Array.0 (module.js:484:10)
    at EventEmitter._tickCallback (node.js:190:39)```

lacking of straightforward example

Hi there,

Thanks for all, it works wonderfully.

I think it would be great to put a really easy example at the top of your README for clarity.

Following example might be obvious for everyone, but it wasn't for me:

$ echo '{"token":"1234"}'  | jsawk 'return this.token'
1234

(feel free to close this issue if you want)

Unable to parse hyphenated names

eg
{"search-results":{"searchTime":"1","total":"326","limit":"100","offset":"0","query":"oc_deleted:false AND oc_latest_version:true","result":[...] } }

~/bin/jsawk 'return this.search-results.results' < ~/a.json

jsawk: js error: ReferenceError: results is not defined

I've tried the usual JS handling of hyphenated words:

return ["this.search-results"] and this.["search-results"] etc without success

/tmp/tmp.VPJk3T:1088:0 ReferenceError: arguments is not defined

Attempted to run your examples and got this error no matter what I do, I cannot even access the help text via '-h'. I built and installed Spidermonkey and have JS working, it's installed to '/opt/spidermonkey/bin/js' and I put a symbolic link in my '~/bin/js' and '/usr/bin/js' to make sure everything works.

JS Version: JavaScript-C25.0a1

Error: /tmp/tmp.VPJk3T:1088:0 ReferenceError: arguments is not defined

Escaped characters

Can't seem to deal with json with escaped characters.

[{
"id": 413,
"description": "This \"String\" can't be processed even though its valid json."
}]

Have tried

curl $URL | jsawk  -n 'out(this["description"])'
// json parse error


curl $URL > json.json
cat json.json |  jsawk  -n 'out(this["description"])'
// json parse error. looking at json.json the " characters seem to be escaped. 

Not sure if I'm missing a special flag but can't see any information in the documentation or examples of how to use the -i flag to load escaped json from file.

Munges unicode-escaped input

When I run jsawk with files that have unicode-escapes in them, these get munged into non-utf-8 binary.

Example:

$ cat simple.json
["these", "so-called \u201cquotes\u201d"]
$ jsawk 'return this' < simple.json
["these","so-called quotes"]

The unicode escapes get replaced with 0X1C and 0X1D, and causes anything expecting utf-8 to subsequently fail if it tries to read.

If unicode-escapes aren't used, it works fine:

$ cat simple2.json
["these", "so-called “quotes”"]
$ jsawk 'return this' < simple2.json
["these","so-called “quotes”"]

memory issues

What's the largest file this is tested with? I'm getting a memory error on a 400MB file.
I have 8GB RAM and watching the bash process go as high as couple of gigs and spit this error while I still have at least 2 more gigs free memory.

js(90609) malloc: *** mmap(size=16777216) failed (error code=12)

Parser does not allow object members with a digit as name

This JSON is valid, but not parsable:
[{"a":[{"port":1,"d-channel":"2","status":"Power on, Provisioned, Down, Active, Standard","type":"CPE","manufacturer":"SIMCOM_Ltd","model_name":"SIMCOM_SIM840W","model_imei":"860041020975176","revision":"Revision:1116B03SIM840W16_MXIC_PCM","operator":"","register":"Not registered","signal":"19","ber":"0","sim_imsi":"208200312507312","sim_sms_center_number":"","remain_time":"No Limit","pdd":"0","asr":"0","acd":"0","last_event":"PIN required","state":"UNKNOW","last_send_at":"","show_status":"<img src="../../images/nosim.gif"/>"}],"2":[{"port":2,"d-channel":"4","status":"Power on, Provisioned, Down, Active, Standard","type":"CPE","manufacturer":"SIMCOM_Ltd","model_name":"SIMCOM_SIM840W","model_imei":"860041020987312","revision":"Revision:1116B03SIM840W16_MXIC_PCM","operator":"","register":"Not registered","signal":"19","ber":"0","sim_imsi":"208200312507313","sim_sms_center_number":"","remain_time":"No Limit","pdd":"0","asr":"0","acd":"0","last_event":"PIN required","state":"UNKNOW","last_send_at":"","show_status":"<img src="../../images/nosim.gif"/>"}],"3":[{"port":3,"d-channel":"6","status":"Power on, Provisioned, Up, Active, Standard","type":"CPE","manufacturer":"SIMCOM_Ltd","model_name":"SIMCOM_SIM840W","model_imei":"860041020969922","revision":"Revision:1116B03SIM840W16_MXIC_PCM","operator":"BOUYGUES TELECOM","register":"Registered (Home network)","signal":"18","ber":"0","sim_imsi":"208200312507321","sim_sms_center_number":"+33660003000","remain_time":"No Limit","pdd":"0","asr":"0","acd":"0","last_event":"D-Channel Up","state":"READY","last_send_at":"","show_status":"<img src="../../images/wifi4.gif"/>"}],"4":[{"port":4,"d-channel":"8","status":"Power on, Provisioned, Up, Active, Standard","type":"CPE","manufacturer":"SIMCOM_Ltd","model_name":"SIMCOM_SIM840W","model_imei":"860041020987304","revision":"Revision:1116B03SIM840W16_MXIC_PCM","operator":"BOUYGUES TELECOM","register":"Registered (Home network)","signal":"16","ber":"0","sim_imsi":"208200312507322","sim_sms_center_number":"+33660003000","remain_time":"No Limit","pdd":"0","asr":"0","acd":"0","last_event":"D-Channel Up","state":"READY","last_send_at":"","show_status":"<img src="../../images/wifi4.gif"/>"}]}]

I change the first member object from "1" to "a", when parsing this is the result (as expected):

root@debiantest:~/JSON.sh# cat /tmp/qqq | jsawk -a 'return this[0].a[0].register'
Not registered

When trying to parse the second object:

root@debiantest:~/JSON.sh# cat /tmp/qqq | jsawk -a 'return this[0].2[0].register'
jsawk: script parse error: 'return this[0].2[0].register'

jsawk should output version info

Would really be helpful for jsawk to output version info like:
jsawk --version
v1.8.2

or even
jsawk -h

version: v1.8.2
usage: jsawk [-n] [-j jsbin] etc......

My preference is for the first option using commandline "--version" as this is similar to most other unix/linus commandline tools

node.js support

I'd like to use node.js to run jsawk instead of spidermonkey

Command not found?

==> devopsgroup.io-dev-redhat: /vagrant/provisioners/redhat/installers/jsawk: line 1317: js: command not found

extract value from property of json object with non alpha numeric characters

StackOverflow question

Example json file content in file /tmp/t

 [
    {
      "name:first"   : "trevor",
      "last"    : "wellington",
      "from"    : "england",
      "age"     : 52,
      "sports"  : [ "rugby", "badmitton", "snooker" ]
    },
    {
      "name:first"   : "yoni",
      "last"    : "halevi",
      "from"    : "israel",
      "age"     : 26,
      "sports"  : [ "soccer", "windsurfing" ]
    },
    {
      "name:first"   : "cory",
      "last"    : "parker",
      "from"    : "united states",
      "age"     : 31,
      "sports"  : [ "windsurfing", "baseball", "extreeeeme kayaking" ]
    }
  ]

This works fine
cat /tmp/t | jsawk -n 'out(this.last)'

But this does not
cat test.json | jsawk -n 'out(this.name:first)'

Error using here documents for input

Whenever I use a here document with jsawk I get a parse error:

$ echo '{ "test": "one" }' | jsawk <<JS
> return this
> JS
jsawk: JSON parse error: 'return this'

While doing the same thing with a regular quoted string works just fine.

$ echo '{ "test": "one" }' | jsawk 'return this'
{"test":"one"}

Unit tests

jsawk could do with some unit tests to make sure that changes - such as bumping the underscore.js version - don't break things in mysterious ways. (Also for comparing the output when run with node.js instead of spidermonkey.)

I'll see what I can lash together as a start.

Update README.markdown

The above file is currently OOD and could do with a small facelift that would make installing jsawk easier.
I'll send a PR in a minute.

jsawk throwing "sed: RE error: illegal byte sequence" response

using the version of jsawk I downloaded today (2015-11-30) I am getting the following response. Using the version I downloaded a month ago (2015-10-29) the command is completing successfully

sed: RE error: illegal byte sequence
[{"id":1,"uuid":"2c504053-ad37-4e6a-a131-f9a4008d1505","url":"https://atmobeta.iplantc.org/api/v2/tags/2c504053-ad37-4e6a-a131-f9a4008d1505","name":"SpliceGrapher","description":""},{"id":2,"uuid":"a098d0f6-1563-41b7-b5f8-2f9a7cf640da","url":"https://atmobeta.iplantc.org/api/v2/tags/a098d0f6-1563-41b7-b5f8-2f9a7cf640da","name":"xGDBvm","description":""},{"id":3,"uuid":"2ff7d144-babc-472a-bf40-905366de6a41","url":"https://atmobeta.iplantc.org/api/v2/tags/2ff7d144-babc-472a-bf40-905366de6a41","name":"R","description":""},{"id":5,"uuid":"ac1af8de-16de-43ee-98a7-36b6154241e5","url":"https://atmobeta.iplantc.org/api/v2/tags/ac1af8de-16de-43ee-98a7-36b6154241e5","name":"QIIME","description":""},{"id":6,"uuid":"a587401b-1cfd-4a2d-b9e6-337e6998c50e","url":"https://atmobeta.iplantc.org/api/v2/tags/a587401b-1cfd-4a2d-b9e6-337e6998c50e","name":"LBNL","description":""},

doing a diff of the jsawk files returns:
diff ~/bin/jsawk_20151029 ~/bin/jsawk_20151130
2,3d1
< export LC_CTYPE=C
< export LANG=C

jsawk: line 1118: js: command not found

EDITED:
Oooops, my bad! I've forgotten to install js :) Shame on me!
Please disregard this issue!

Thanks a lot!


Hi!
I'm trying to use jsawk under MacOS X, but I am getting the following error:

PM0270:~ lyubovberezina$ curl -s "https://api.github.com/repos/antirez/redis" | jsawk "return this.open_issues"
/usr/local/bin/jsawk: line 1118: js: command not found

Thanks!

Inserting Elements with JSON to JSON Mutations

Is there currently a way to define elements that do not exist in the input JSON?

For example, take the following script snippet that might be run in an ssh window:

cat /etc/example/example.conf | 
                jsawk \"this.pools[0].url='somewhere\" | 
                jsawk \"this.pools[0].user='me'\" | 
                jsawk \"this.pools[1].url='somewhere'\" |
                jsawk \"this.pools[1].user='me'\" |
                jsawk \"this.pools[1].pass='x'\" |
                jsawk \"this.failover-only=true\" |
                json_reformat >> /etc/example/example.conf.new;

Assuming all of the elements above exist, their values will be properly reassigned. However, if for instance this.pools[1] did not exist, jsawk will opt to throw an error instead of defining the object.

Is there a way to override this behavior and instead instruct jsawk to define currently undefined elements?

Thank you!

Parser does not allow object members to start with a digit.

Here's a broken test:

~$ cat tmp
{ "902" :
{
"first" : "trevor",
"last" : "wellington",
"from" : "england",
"age" : 52,
"sports" : [ "rugby", "badmitton", "snooker" ]
}
}

~$ cat tmp | jsawk 'return this.902'
jsawk: script parse error: 'return this.902'

Syntax error calling eval() on anonymous functions

The version of spidermonkey I have (custom compile of 1.8.1) is unhappy with the eval function used to parse the jsawk script.

line 933:

window.makeFilter = function(fun) {
  try {
    return eval("function() { "+fun+"; return this }");
  } catch (e) {
    err("jsawk: script parse error: '"+fun+"'");
    quit(3); 
  }
}; 

Wrapping the anonymous function creation in parentheses works for me.
return eval("(function() { "+fun+"; return this })");

Help with accessing Array elements.....

Hello, I was wondering if someone might be able to help me with jsawk and how to access/print each element in the below log array w/n a json document. I'm having trouble understanding how to do this....

{
"device_id": "4FB9B235848E2E6E73A507186771A3E3",
"logs": [
{
"id": 21,
"activity": "physician/249",
"timestamp": "2012-02-04 00:07:26"
},
{
"id": 22,
"activity": "physician",
"timestamp": "2012-02-04 00:08:07"
},
{
"id": 23,
"activity": "physician/1196",
"timestamp": "2012-02-04 00:08:17"
}
],
"user_device": "Apple/iPhone4,1/iPhone OS/5.0.1/3.3"
}

Parse error when key name starts with a number

jsawk fails to extract a value for a key when it's name starts with a number.
(or name of any key in the chain)

This works fine:

echo '{"val1":"v1","2val":"v2"}' | ./jsawk "return this.val1"
v1

This fails:

echo '{"val1":"v1","2val":"v2"}' | ./jsawk "return this.2val"
jsawk: script parse error: 'return this.2val'

bug in forEach usage of eval()

forEach suffers from the same bug that was mentioned and closed in #4 :

line 1167:

  window.forEach = function(ary, funct) {
    fun = eval("function(index,item) { "+funct+"; }");
    for (var i=0; i<ary.length; i++) {
      try {
        fun.call(ary[i], i, ary[i]);
      } catch (e) {
        err("jsawk: js error: "+e);
        quit(3);
      }
    }
  };

replacing the eval() with

fun = eval("(function(index,item) { "+funct+"; })");

fixes the issue by wrapping the anonymous function creation in parentheses. I haven't reviewed other usages of eval() but it may be worth taking a look.

Output a new JSON object

I need to iterate over output from Couchdb - /_all_dbs, which looks like this:

["db1","db2","db3","db4"]

and use those DB names to build a new JSON object that looks something like this:

{
  docs: [
    {name: db1},
    {name: db2},
    {name: db3}
  ]
}

it uses input values as parameters values. I couldn't achieve that so far. Is there a way to do that?

Cannot invoke usage() function

When I attempt to invoke help I am greeted by a lovely command not found error.
We should fix this as a basic requirement for running the script.
PR hopefully coming up soon.

LMC-032857:jsawk lmcgibbn$ ./jsawk -h
./jsawk: line 1318: js: command not found

output version info similar to other unix commands

Would be nice/useful if jsawk would output its version info similar to other unix commandline utilities
"jsawk -v" or "jsawk --version"

ie:
diff --version
diff (GNU diffutils) 2.8.1
Copyright (C) 2002 Free Software Foundation, Inc.

This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of this program
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.

Written by Paul Eggert, Mike Haertel, David Hayes,
Richard Stallman, and Len Tower.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.