jsonsed

use sed to replace version number in a package.json file


This is a part of my package.json file

{
    "name": "org-team-module",
    "version": "1.1.0-snapshot",
    "description": "Some description",
    "scripts": {
        "start": "npm run build && npm run copy-static-assets && npm run serve",
        "build": "rimraf dist && npx tsc && echo npm run lint",

I want to replace the version with a particular value, say 1.2.0-snapshot

This is what i have till now;

sed -nE -i 's/(^\s*"version": ")(.*?)(",$)/\11.2.0-snapshot\3/p' test.json

However when I add the -i flag to replace; the entire file gets replaced with the searched value. i.e. the entire file contents after replace is

        "version": "1.2.0-snapshot",

How can i just replace that particular line in the file


Solution

  • sed is not appropriate to work with JSON files; your script will fail if "version" and its value are not on the same line (not a common situation but definitely valid JSON).

    I suggest to use jq instead. It knows how to parse and generate JSONs and the script becomes smaller and more clear.

    Replacing the value of version with a fixed value is as simple as:

    jq '.version="1.2.0-snapshot"' package.json
    

    It does not modify the original file but dumps the modified JSON on screen. Your script can redirect its output to a temporary file then move the temporary file over the original file, like this:

    jq '.version="1.2.0-snapshot"' package.json > /tmp/package.json
    mv /tmp/package.json package.json
    

    Since the version is constantly changing, do not hardcode it in the script or build the JQ program using string concatenation. Pass the version to jq in the command line, using option --arg:

    # Replace this with your algorithm to compute the version
    VERSION=1.2.0-snapshot
    
    # Regenerate `package.json`
    jq --arg ver "$VERSION" '.version=$ver' package.json > /tmp/package.json
    mv /tmp/package.json package.json