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.