One implementation for a naive approach would be very simple:
sort -k1,1 -k2,2Vr file | sort -k1,1 -u
i.e: sort by first field (package name) ascending, and by second field (version) descending using -V
/--version-sort
(natural sort for version numbers). Then in the second pass (second sort
invocation, with -u
/--unique
flag) simply compare by package name only and drop all duplicates (packages with the same name but smaller version number, since after the first pass greater versions will appear at the top).
The result for your sample input is:
"grunt": "1.0.1",
"grunt-angular-templates": "0.5.7",
"grunt-cli": "^0.1.13",
"grunt-contrib-clean": "0.6.0",
"grunt-contrib-compress": "0.12.0",
"grunt-contrib-concat": "1.0.1",
However, since npm
(and I'm assuming those are lines from package.json
) uses semantic versioning (semver), properly handling semver sorting is a lot more complex than the above sort
approach can handle.
For example, you would have to sort versions like >=version
, ~version
, ^version
, version1 - version2
, even range1 || range2
, and even URLs, files/paths, GitHub URLs, tags, etc.
To handle all those (valid) versions, it's best to use a specialized tool, for example semver
.