Home > Software design >  List files that match list whithout duplicates keep highest version number
List files that match list whithout duplicates keep highest version number

Time:01-13

Sorry if this is a repeated question but I have been looking for several hours.

I have a list of files generated by

find /usr/lib64/ -maxdepth 1 -type l -printf "%f\n"

that print something like

libncurses.so.6
libaudit.so.1
libncurses.so.5
libicuuc.so.65
libnghttp2.so.14
libicuuc.so.71

I would like to keep only the files with the highest vesion number

libncurses.so.6
libaudit.so.1
libnghttp2.so.14
libicuuc.so.71

Thanks lot for your help

CodePudding user response:

maybe with awk?

find /usr/lib64/ -maxdepth 1 -type l -printf '%f\n' |
awk -F '\\.so\\.' -v OFS='.so.' '
    $2 > vers[$1] { vers[$1] = $2 }
    END { for (lib in vers) print lib, vers[lib] }
'
libaudit.so.1
libicuuc.so.71
libnghttp2.so.14
libncurses.so.6

note: you might need to implement a more accurate operator than > for comparing versions, or use:

find /usr/lib64/ -maxdepth 1 -type l -printf '%f\n' |
sort -rV |
awk -F '\\.so\\.' -v OFS='.so.' '!seen[$1]  '

CodePudding user response:

You could chain some commands with a pipe, something like:

find /usr/lib64/ -maxdepth 1 -type l -printf "%f\n" | 
  sort -rn -k3 -t. |
  awk -F. '!seen[$1]  '

The code above assumes that there are always 3 fields/column separated by a dot . from the file names.


With pure bash using associative array with GNU find and sort

#!/usr/bin/env bash

declare -A uniq

while IFS= read -rd '' files; do
  if ((!uniq[${files%%.*}]  )); then
    printf '%s\n' "$files"
  fi
done < <(
  find /usr/lib64/ -maxdepth 1 -type l -printf "%f\0" |
  sort -rnz -k3 -t.
)

CodePudding user response:

You can use the following to sort:

find /usr/lib64/ -maxdepth 1 -type l -printf "%f\n" | sort -V

To only keep the latest version:

find /usr/lib64/ -maxdepth 1 -type l -printf "%f\n" | sort -V | uniq -f2

-f2 ignores the first two fields when comparing lines.

  •  Tags:  
  • bash
  • Related