Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use jq in Bash to sort object properties by descending length of their value

I have the following JSON snippet:

{
    "root_path": "/www",
    "core_path": "/www/wp",
    "content_path": "/www/content",
    "vendor_path": "/www/vendor"
}

I would like to use jq first to get the values sorted in descending order of length:

/www/content
/www/vendor
/www/wp
/www

I need these so I can match against a list of files to find which of the named paths the files exist in.

Then I would like to use jq again to swap properties for values (it can drop duplicate properties, that's okay):

{
    "/www": "root_path".
    "/www/wp": "core_path",
    "/www/content": "content_path",
    "/www/vendor": "vendor_path"
}

My use case for this 2nd query is to be able to lookup a matched path value and find its path name, which I will then use in a second JSON snippet with an identical schema to get the named path's value.

My use-case is for website deployment and I have a config file that contains files names as they will exist on the deployment server that should be copied from the source server to the deploy server but the servers may have different directory layouts.

I need to use Bash for this, but if there is a better way to do what I am looking to do I am open. That said, I really do want to learn how to use jq better so I would prefer to learn how to use jq to do these transforms.

I am using jq version 1.5

like image 869
MikeSchinkel Avatar asked Aug 19 '18 03:08

MikeSchinkel


1 Answers

the values sorted in descending order of length:

[.[]] | sort_by(length) | reverse[]

swap properties for values

with_entries(.key as $k | .key=.value | .value=$k )

Combining the two requirements

A solution to the combined problem can be crafted by combining the above two solutions, because with_entries is a combination of to_entries and from_entries:

to_entries
| map(.key as $k | .key=.value | .value=$k )
| sort_by(.key|length)
| reverse
| from_entries
like image 73
peak Avatar answered Sep 18 '22 11:09

peak