3

How can I retrieve the version attribute from the following json file AND use it in a BASH script?..

file package.json

{
  "name": "myapp",
  "version": "0.0.1"
}

desired script: bpush.sh

#!/bin/bash
gulp bump
git add -A
eval $pkg_ver = getjson('./package.json', 'version')
git commit -a -m "$pkg_ver"
git push origin master

Obviously, the getjson() function is invalid. That is what I'm trying to figure out.

Edit: Final Result
Here's what I used, thanks to the folks below...

#!/bin/sh

pkg_ver=$(jq '.version' package.json)
pkg_ver=${pkg_ver//\"/}
git add -A
git commit -a -m $pkg_ver
git push origin master
2
  • pkg_ver=$(tr -cd '[0-9.]' < package.json)? Commented Sep 6, 2016 at 20:22
  • There is no need for eval here; just use pkg_ver=$(...), where ... will be provided by an acceptable answer. Commented Sep 6, 2016 at 20:29

3 Answers 3

6

If your json file is more complex then I would suggest to use jq - link

pkg_ver=$(jq '.version' package.json)

However, if you have only this two items then maybe using sed, awk or tr would be easier.

Sign up to request clarification or add additional context in comments.

4 Comments

Maybe $pkg_ver = $(jq '.version' <package.json) ?
@DavidC.Rankin Yes, I forget about the file.
Happens, we could tell what you intended to do. Good job on jq recommendation.
Thanks, guys. I used jq and stripped off the quotes. (See the edit above.)
4

Why not using itself from a here-doc ? :)

Remember, JS stands for JavaScript Object Notation

pkg_ver=$(
    node<<EOF
    var obj = $(<package.json);
    console.log(obj.version);
EOF
)

Replace node by the nodejs executable or if you don't have node

Or as a one-liner :

node <<< "var obj = $(<package.json); console.log(obj.version);"

5 Comments

Perhaps you want var obj = $(< package.json )? The goal is to be reading from an input file, after all -- but since your heredoc sigil isn't quoted, you can use that kind of expansion there.
BTW, does console.log go to stdout or stderr? If the latter, you'll need to do a redirection to make sure it gets captured. Wouldn't hurt to wrap the whole thing in a command substitution for demonstrative purposes.
You're right for $(< package.json ); I saw your comment after my edit :)
nod. This is a good answer -- my only hesitancy in upvoting it is not being sure if its output can be captured with a command substitution on account of the stdout/stderr thing. Logging intended for human consumption conventionally goes to stderr, after all; if I had node installed I'd test, but...
Glad to have that confirmation.
1

You can use also python one-liner

pkg_ver=$(
    python -c 'import sys,json; print(json.load(sys.stdin)["version"])' \
    < package.json
)

or even

pkg_ver=$(
    python -c 'import sys,json;print(json.load(open("package.json"))["version"])'
)

5 Comments

Better to take out the cat and use <package.json -- that way you have a direct handle on the input file rather than a FIFO connected to a separate process. See also porkmail.org/era/unix/award.html
@CharlesDuffy yeah, you are right! thanks :) I'll edit my answer
hmm, I'm also not sure json.loads(open("foo")) works, since loads() is to load a string. Do you mean json.load(open(...))?
@CharlesDuffy yeah, that was a typo :(
BTW, to support passing in a filename rather than hardcoding it, consider: python -c 'import sys,json;print(json.load(open(sys.argv[1]))["version"])' "${1:-package.json}" -- that way it isn't vulnerable to code injection attacks the way it could be if someone naively used open("'"$1"'") to modify your code to use a filename given as an argument.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.