edit:add-var cleankh~ {|@argv| use re use str use framagit.org/benjamin.vaudour/elv-lib/mods/common use framagit.org/benjamin.vaudour/elv-lib/mods/ip use framagit.org/benjamin.vaudour/elv-lib/mods/list var hosts = [&] var ips = [&] var ids = [&] var file = $E:HOME/.ssh/known_hosts fn readfile { cat $file | each {|l| if (not (str:has-prefix $l '#')) { put $l } } | re:awk {|_ host @rest| var id = (str:join ' ' $rest) var ihosts = [] str:split ',' $host | each {|h| set @ihosts = $@ihosts $h if (ip:is-ip $h) { if (not (has-key $ips $h)) { set ips[$h] = [ $id ] } else { set ips[$h] = [ (all $ips[$h]) $id ] } } else { if (not (has-key $hosts $h)) { set hosts[$h] = [ $id ] } else { set hosts[$h] = [ (all $hosts[$h]) $id ] } } } } } fn searchips {|id| if (has-key $ids $id) { each {|h| if (ip:is-ip $h) { put $h } } $ids[$id] } } fn hashost {|id| if (has-key $ids $id) { list:contains {|h| not (ip:is-ip $h) } $ids[$id] } else { put $false } } fn formatlines { keys $hosts | order | each {|h| order $hosts[$h] | each {|id| var hid = (str:join ',' [ $h (searchips $id) ]) put $hid $id | str:join ' ' } } keys $ips | list:sort $ip:comp~ | each {|ip| order $ips[$ip] | each {|id| if (not (hashost $id)) { put $ip $id | str:join ' ' } } } } readfile var @lines = (formatlines) echo (str:join "\n" $lines) > $file }