How to sort files by part of the filename?

26,606

Solution 1

In this particular case where your file names don't contain any whitespace or other strange characters, you can use ls and pipe it through sort:

$ ls -d -- *.SC* | sort -t. -k2
XYZ38390.SC00.Statue_WKP
ABC38388.SC01.StatueGrade_MKP
ABC38388.SC02.Statue_GKP
DEF38389.SC03.Statue_HKP

The -t sets the field delimiter and the -k2 tells sort to sort based on the part of the line starting with the 2nd field (use -k2,2 for second field only).

For more complex cases, you could print each file name followed by the NULL character (\0), then pipe to GNU sort using its -z option to tell it to read NULL-delimited lines and, finally, use tr to change the \0 back to \n:

printf '%s\0' *SC* | sort -zt. -k2 | tr '\0' '\n'

Solution 2

With zsh, you can define your own sorting order for globs with the oe or o+ glob qualifiers:

ls -lUd -- *(oe['REPLY=${REPLY#*.SC}'])

or:

bysc() REPLY=${REPLY#*.SC}
ls -lUd -- *(o+bysc)

The sorting function receives the filename in $REPLY and is meant to return a string in $REPLY that globbing will sort on. Here, we return the part of the file name to the right of the first occurrence of .SC (or the full filename if it doesn't contain .SC).

Solution 3

On a GNU system and with zsh or bash as your shell, use this:

find -maxdepth 1 -type f -print0 | sort -z -t. -k3 | \
while IFS="" read -r -d "" f; do
  basename "$f"
done

  • find searches for the files in the current directory (-maxdepth 1) and prints them null-byte delimited (-print0).
  • sort reads its input null-byte delimited (-z) and sorts on the part of the record that starts on the 3rd field (-k3) separated by a dot (-t.).
  • while reads the input
    • and basename prints its name without path
Share:
26,606

Related videos on Youtube

MRKR
Author by

MRKR

Updated on September 18, 2022

Comments

  • MRKR
    MRKR almost 2 years

    Given the files below:

    ABC38388.SC01.StatueGrade_MKP
    ABC38388.SC02.Statue_GKP
    DEF38389.SC03.Statue_HKP
    XYZ38390.SC00.Statue_WKP
    

    How can I list them all based on the SC value, like this:

    XYZ38390.SC00.Statue_WKP
    ABC38388.SC01.StatueGrade_MKP
    ABC38388.SC02.Statue_GKP
    DEF38389.SC03.Statue_HKP
    
  • MRKR
    MRKR over 8 years
    Thanks all... "-k" parameter in sort is confusing for me... on what basis did it pick up the field is confusing me... like k2 for second field ?
  • terdon
    terdon over 8 years
    @MRKR the -t. tells it to use . as the field separator so the -k2 refers to the second field as defined by ..
  • terdon
    terdon over 8 years
    @MRKR If one of the answers here solved your issue, please take a moment and accept it by clicking on the check mark to the left. That will mark the question as answered and is the way thanks are expressed on the Stack Exchange sites.