0

How do I sort by the last column a list which looks like this:

drwxr-sr-x   2 user     group           4096 2018-02-19 14:11:42  /something/project/somefile
drwxr-sr-x   2 user     group           4096 2018-02-19 00:14:50  /blah-blah/anything
-rw-r-----   1 someone  users           2188 2018-07-21 13:52:59  /aaa/222
drwxr-S---   2 someone  users           4096 2018-06-25 14:27:42  /bbb/333/anything/whatever
-rw-r-----   1 someone  users            715 2018-06-16 20:09:58  /xxx/aaa/666

*The list is in a file but not generated by ls so I cannot use ls's functionality.

1 Answer 1

2

You can use sort:

sort -k8,8 <<EOF
drwxr-sr-x   2 user     group           4096 2018-02-19 14:11:42  /something/project/somefile
drwxr-sr-x   2 user     group           4096 2018-02-19 00:14:50  /blah-blah/anything
-rw-r-----   1 someone  users           2188 2018-07-21 13:52:59  /aaa/222
drwxr-S---   2 someone  users           4096 2018-06-25 14:27:42  /bbb/333/anything/whatever
-rw-r-----   1 someone  users            715 2018-06-16 20:09:58  /xxx/aaa/666
EOF

-k selects which field to sort on, 8,8 says to sort on data from field 8, to field 8.

You can use -t to define the field separator, though the default here is fine (non-blank to blank transition).

Output:

-rw-r-----   1 someone  users           2188 2018-07-21 13:52:59  /aaa/222
drwxr-S---   2 someone  users           4096 2018-06-25 14:27:42  /bbb/333/anything/whatever
drwxr-sr-x   2 user     group           4096 2018-02-19 00:14:50  /blah-blah/anything
drwxr-sr-x   2 user     group           4096 2018-02-19 14:11:42  /something/project/somefile
-rw-r-----   1 someone  users            715 2018-06-16 20:09:58  /xxx/aaa/666

To followup, you asked:

My file containing the list also has N starting and M ending lines which are not in the column-like form shown above. Unfortunately the sorting messes them up. How can I exclude those lines and sort just the columned ones?

You'll need to know how many lines are before / in / after the block to be sorted, and you can substitute the values used below with variables. A simple pipeline like shown below can work well.

Content of data.txt:

Zline1
Zline2
drwxr-sr-x   2 user     group           4096 2018-02-19 14:11:42  /something/project/somefile
drwxr-sr-x   2 user     group           4096 2018-02-19 00:14:50  /blah-blah/anything
-rw-r-----   1 someone  users           2188 2018-07-21 13:52:59  /aaa/222
drwxr-S---   2 someone  users           4096 2018-06-25 14:27:42  /bbb/333/anything/whatever
-rw-r-----   1 someone  users            715 2018-06-16 20:09:58  /xxx/aaa/666
AlineN-1
AlineN

Pipeline:

(head -n 2; head -n 5 | sort -k8,8; cat) < data.txt

Output:

Zline1
Zline2
-rw-r-----   1 someone  users           2188 2018-07-21 13:52:59  /aaa/222
drwxr-S---   2 someone  users           4096 2018-06-25 14:27:42  /bbb/333/anything/whatever
drwxr-sr-x   2 user     group           4096 2018-02-19 00:14:50  /blah-blah/anything
drwxr-sr-x   2 user     group           4096 2018-02-19 14:11:42  /something/project/somefile
-rw-r-----   1 someone  users            715 2018-06-16 20:09:58  /xxx/aaa/666
AlineN-1
AlineN
4
  • Thanks! May I also ask: my file containing the list also has N starting and M ending lines which are not in the column-like form showne above. Unfortunately the sorting messes them up. How can I exclude those lines and sort just the columned ones?
    – george
    Nov 15, 2018 at 16:34
  • 1
    See my update :-)
    – Attie
    Nov 15, 2018 at 17:03
  • Thank you! Actually I found that (head -n <N>; tail -n +<N+1> | head -n -<M> | sort -s -k8,8; tail -n <M>) < data.txt also works (without having to know the number of lines in the "middle"). Unfortunately the last M lines are missing, so I had to do it as a separate line in the script. Perhaps if you know how to pipeline it (as I may be wrong) it would be perfect :) But this works too!
    – george
    Nov 15, 2018 at 17:25
  • Using tail won't work, because it has to read the full input in to figure out how many lines from the end to use... so in that case the final tail -n <M> gets nothing on stdin, because the previous tail -n +<N+1> has taken it all!
    – Attie
    Nov 15, 2018 at 17:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .