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

For discussions about programming, and for programming questions and advice


Moderator: Forum moderators

Post Reply
User avatar
fredx181
Posts: 3246
Joined: Tue Dec 03, 2019 1:49 pm
Location: holland
Has thanked: 407 times
Been thanked: 1409 times
Contact:

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

Post 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.

User avatar
fredx181
Posts: 3246
Joined: Tue Dec 03, 2019 1:49 pm
Location: holland
Has thanked: 407 times
Been thanked: 1409 times
Contact:

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

Post 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)

User avatar
MochiMoppel
Posts: 1289
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 22 times
Been thanked: 476 times

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

Post 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

jamesbond
Posts: 720
Joined: Tue Aug 11, 2020 3:02 pm
Location: The Pale Blue Dot
Has thanked: 124 times
Been thanked: 406 times

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

Post 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

Post Reply

Return to “Programming”