Reputation: 2717
I need to replace a hash for a file in manifest. My problem is I don't know the original hash, only the new one.
mainfest:
[
{
"file": "bundle.js",
"hash": "0a4c61f0cf23ca1fd39c411140941cd5"
},
{
"file": "0fdbe5712e250dac1fa5930395f65a27.jpg",
"hash": "0fdbe5712e250dac1fa5930395f65a27"
}
]
As you could see, in the manifest (JSON) file name and hash are bundled in an object.
I want to change the hash file for the bundle.js with a new one. I use below shell script with sed and regular expression to replace the hash.
shell script:
#!/bin/sh
NEW_HASH="$(md5 < ./scripts/bundle.js)"
sed 's/\({"file": "bundle.js","hash": "\).*\("}\)/\1'$NEW_HASH'\2/g' chcp.manifest
Only I don't know how to match the multiple lines. Mine regex matches only a single line
{"file": "bundle.js","hash": "0a4c61f0cf23ca1fd39c411140941cd5"}
and not
{
"file": "bundle.js",
"hash": "0a4c61f0cf23ca1fd39c411140941cd5"
}
I tried something like:
sed 's/\({"file": "bundle.js",\n "hash": "\).*\("\n }\)/\1'$NEW_HASH'\2/g' chcp.manifest
but \n doesn't seam to work for matching a new line
Upvotes: 0
Views: 79
Reputation: 311606
Trying to parse a structured format like JSON (or XML, etc) with something like sed
or awk
is tricky and never as robust as using a tool actually designed to parse the data with which you're working.
Your task would be relatively trivial using Python or Ruby or Perl or something else with a JSON parser. For shell scripts, you may want to investigate the jq command, which is available as a package for most distributions.
Using jq
, you could use the technique described in this document, which would boil down to:
NEW_HASH="$(md5 < ./scripts/bundle.js)"
jq 'map(if .file == "bundle.json"
then . + {"hash": "'"$NEW_HASH"'"}
else .
end)' chcp.manifest
That would generate the new document on stdout; you could obviously save that to a file and then rename that to replace the original.
Upvotes: 2