5

I would like to sort the dired buffer by a suffix in the file names. For instance, with the following buffer content:

/nixos/nix/store:
total used in directory 140344 available 17530560
drwxrwxr-t 1612 root  30000  1810432 Mar  4 21:41 .
drwxr-xr-x    4 root  root      4096 Feb  4  2015 ..
dr-xr-xr-x    5 root  root      4096 Dec 31  1969 01l09wxficgyw6yhd812xzxldxrp4yma-pangomm-2.34.0
dr-xr-xr-x    5 root  root      4096 Dec 31  1969 03afp0sdvnvj9aj8k18s7ikkh4pnzlij-perl-HTTP-Message-6.06
dr-xr-xr-x    4 root  root      4096 Dec 31  1969 04yx1lnhzbiy4hkwkhnw7cw2i6zmfhf4-xmlto-0.0.26
dr-xr-xr-x    3 root  root      4096 Dec 31  1969 0534201di00hs189hzvx8gv8kxgbl2q1-unit-script
dr-xr-xr-x    2 root  root      4096 Dec 31  1969 06g99nk2q4pjq4xx3p6qw77zxmnyr5rn-kmod-blacklist-3ubuntu1
dr-xr-xr-x    4 root  root      4096 Dec 31  1969 06l8iksb8mndiis047z5f7b1zaqc1i4a-feh-2.14
dr-xr-xr-x    4 root  root      4096 Dec 31  1969 06s10661ji3s3cwsmrxc38kx856jds8i-nixos-system-jrm.no-ip.org-16.03pre77568.40c586b
dr-xr-xr-x    5 root  root      4096 Dec 31  1969 06wqzjsbjlhimn18g9ah04klhslj8b04-libkrb5-1.14
dr-xr-xr-x    7 root  root      4096 Dec 31  1969 06xdwfrhbjwhgxcsp2d2qlxhkv3ck01b-gcc-4.9.3
dr-xr-xr-x    3 root  root      4096 Dec 31  1969 079ix6d3aarvjjh83r7vcc6nk9pjcb25-mesa-noglu-11.1.1-drivers
dr-xr-xr-x    2 root  root      4096 Dec 31  1969 07k6b606sxwfib3f1srbdi1pifpb9gj3-unit-firewall.service
dr-xr-xr-x    5 root  root      4096 Dec 31  1969 07yqgv4n248xrigrnk9xn7ami5dyz3q8-lzo-2.09
dr-xr-xr-x    5 root  root      4096 Dec 31  1969 09i3xn0lbi268354l9y2nm8302qc5dhg-poppler-qt4-0.36.0
drwxr-xr-x    2 30001 30000     4096 Mar  4 20:39 09jszxa0cdd65g7yxb64fc87dq7ayy5s-jwm-s1406
dr-xr-xr-x    6 root  root      4096 Dec 31  1969 0ac359cfc4a8kw95g494z0x5vn37vrqa-libwacom-0.15

the file names consists of a hash sequence, followed by an -, followed by a suffix (the really interesting part of the name). I want to sort by this last part.

How can this be achieved?

4

Dired relies on the ls command to do the listing and the sorting. The options for sorting are limited to what the ls command can do (via switches added with C-u s (dired-sort-toggle-or-edit)). On ELPA, I can find packages that make it easier to change the ls switches, but not packages that allow the sort order to be customized.

It seems that the only way to customize the sort order is to invoke your own program instead of ls. The program invoked is determined by the insert-directory-program variable. So you could set it locally to a wrapper that calls ls and then sorts the result. Here's a shell wrapper you can use; put that in a script, make it executable (M-x chmod with the permission +x), and set insert-directory-program to that locally.

#!/bin/sh
ls_output=$(ls "$@")
nl='
'
echo "${ls_output%%"$nl"*}" # The total... line
ls_output=${ls_output#*"$nl"}
# Isolate the //DIRED stuff, which must go last
case "$ls_output" in
  *"$nl//DIRED"*)
    dired_stuff="//DIRED${ls_output##*"$nl//DIRED"}$nl"
    ls_output="${ls_output%"$nl//DIRED"*}";;
  *) dired_stuff=;;
esac
# Now sort, ignoring the first 8 fields (metadata) and the first 33 characters of the 9th field
printf '%s\n' "$ls_output" | sort -k 9.34
printf '%s' "$dired_stuff"

Then

M-: (make-local-variable 'insert-directory-program) RET
M-: (setq insert-directory-program "/path/to/wrapper") RET
  • It seems that echo "${ls_output%"$nl"*}" is not selecting the total... line as expected. It is outputting the full list. – Romildo Mar 8 '16 at 19:27
  • @Romildo Stripping away the last line, actually, instead of stripping all lines but the first. I've fixed this and a couple other problems. – Gilles 'SO- stop being evil' Mar 8 '16 at 20:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.