Page 1 of 1

Question about sort uniq by last field (basename) [SOLVED]

Posted: Sat Aug 31, 2024 5:41 pm
by fredx181

Say I have a file with contents for example:

Code: Select all

/root/.local/share/applications/Brave-Portable64.desktop
/root/.local/share/applications/vlc.desktop
/root/.local/share/applications/google-chrome.desktop
/usr/share/applications/abiword.desktop
/usr/share/applications/geany.desktop
/usr/share/applications/evince.desktop
/usr/share/applications/deadbeef.desktop
/usr/share/applications/vlc.desktop
/usr/share/applications/google-chrome.desktop
/usr/share/applications/lxrandr.desktop

I'd like to modify by keeping only the (that are double above) .desktop entries (vlc.desktop and google-chrome.desktop in this case) that are in /root/.local/share/applications/ , so that it becomes:

Code: Select all

/root/.local/share/applications/Brave-Portable64.desktop
/root/.local/share/applications/vlc.desktop
/root/.local/share/applications/google-chrome.desktop
/usr/share/applications/abiword.desktop
/usr/share/applications/geany.desktop
/usr/share/applications/evince.desktop
/usr/share/applications/deadbeef.desktop
/usr/share/applications/lxrandr.desktop

(without vlc.desktop and google-chrome.desktop from /usr/share/appications/)
I know there's option to sort -u by column number (with delimiter /), but here the column numbers are different from each other and can't make it work in some way.


Re: Question about sort uniq by last field (basename)

Posted: Sat Aug 31, 2024 7:06 pm
by fredx181

I think I found something. Modified a bit from the answer here: https://unix.stackexchange.com/a/394166
cat mylist | sed 's|\(.*\)/|\1@|' | sort -u -t@ -k+2 | sed 's|@|/|'
Or, less compact, but probably better for my needs (to keep the /root/.local/... entries on top:
cat mylist | sed 's|\(.*\)/|\1@|' | sort -u -t@ -k+2 | sed 's|@|/|' | sort
(not sure yet if supports .desktop names with space(s) in it. edit: seems it does)


Re: Question about sort uniq by last field (basename)

Posted: Sun Sep 01, 2024 1:29 am
by MochiMoppel

Should also work:
rev mylist | sort -t/ -uk1,1 | rev | sort

Similar to your approach but more robust because it doesn't rely on an "unlikely to appear in file names" divider character:
sed -r 's|(.*/)(.*)|\2\1\2|' mylist | sort -t/ -uk1,1 | sed 's|[^/]*||' | sort


Re: Question about sort uniq by last field (basename) [SOLVED]

Posted: Sun Sep 01, 2024 8:59 am
by jamesbond

Assuming that list is exactly as specified, where the /root/.local entries are always located earlier in the list, this will produce the expected output where entries are in the same order as the original list.

awk -F / '{if (!seen[$NF]) print $0; seen[$NF]=1}' mylist