1

I'm trying to modify the deluge web.conf file with jq and I'm having some issues. The deluge web config seems to be invalid json

{
  "file": 1,
  "format": 1
}
{
  "sidebar_show_zero": false,
  "show_session_speed": false,
  "pwd_sha1": "CHANGEME",
  "show_sidebar": true,
  "sessions": {},
  "enabled_plugins": [],
  "base": "/",
  "first_login": true,
  "theme": "gray",
  "pkey": "ssl/daemon.pkey",
  "default_daemon": "",
  "cert": "test",
  "session_timeout": 3600,
  "https": false,
  "interface": "0.0.0.0",
  "sidebar_multiple_filters": true,
  "pwd_salt": "salt",
  "port": 8112
}

It has multiple top level elements which aren't separated by a comma so if I try to edit the file with jq using something like this jq '.pwd_sha1 = "NEW HASH"' web.conf I get the following

{
  "file": 1,
  "format": 1,
  "pwd_sha1": "NEW HASH"
}
{
  "sidebar_show_zero": false,
  "show_session_speed": false,
  "pwd_sha1": "NEW HASH",
  "show_sidebar": true,
  "sessions": {},
  "enabled_plugins": [],
  "base": "/",
  "first_login": true,
  "theme": "gray",
  "pkey": "ssl/daemon.pkey",
  "default_daemon": "",
  "cert": "test",
  "session_timeout": 3600,
  "https": false,
  "interface": "0.0.0.0",
  "sidebar_multiple_filters": true,
  "pwd_salt": "salt",
  "port": 8112
}

jq is adding a new element to the first top level object and changing the second top level element's value. How can I get this to only change the existing item in the second top level element?

peak
  • 105,803
  • 17
  • 152
  • 177
vane
  • 2,125
  • 1
  • 21
  • 40
  • 1
    `jq 'if has("pwd_sha1") then .pwd_sha1="NEW_HASH" else . end' web.conf`; but why not `deluge-console 'config -s pwd_sha1 "NEW_HASH"'`? – Amadan Jan 06 '19 at 23:06
  • 1
    @Amadan that works but I can't do `deluge-console` since this is a docker image and I'm applying the config in a bash installation script. I could probably use it, but it would be more complicated than just using `jq` – vane Jan 07 '19 at 01:04

1 Answers1

2

The web.conf you show is a stream of JSON entities. Fortunately for you, jq is stream-oriented, and it appears from your example that you could simply write:

jq 'if .pwd_sha1 then .pwd_sha1 = "NEW HASH" else . end' web.conf

In general, though, it might be more appropriate to write something with a more stringent test, e.g.

jq 'if type == "object" and has("pwd_sha1") 
  then .pwd_sha1 = "NEW HASH" else . end' web.conf

"changing the second top level element's value"

To edit the second top-level item only, you could use foreach inputs with the -n command-line option:

foreach inputs as $in (0; .+1; 
  if . == 2 then $in | .pwd_sha1 = "NEW_HASH" 
  else $in end)
peak
  • 105,803
  • 17
  • 152
  • 177
  • this works but you need to change `if .pwd_sha1` to `if has("pwd_sha1")` otherwise it won't match on existing items with a `false` value – vane Jan 08 '19 at 04:10
  • @vane - Did you read the paragraph beginning "In general, though, ..."? – peak Jan 08 '19 at 04:55
  • yes, but even with that, the first statement is still incorrect since it will fail in some cases and you won't know why – vane Jan 09 '19 at 09:42