Sort only numbers within a string

Hi,

I am having contents in a file like below,

cat testfile
rpool/swap
rpool/swap14
rpool/swap2
rpool/swap3

I want to sort the above contents like,

rpool/swap
rpool/swap2
rpool/swap3
rpool/swap14

I have tried in this way,

sort  -n -k2 testfile

Where am i doing wrong?

OS:Solaris11x86

TIA

sort -t/ -k2.5n testfile

SunOS sol 11.4

The sort fields are "blank"-delimited by default.
You would need a preformatting like

sed 's/[0-9]\{1,\}/ &/g' testfile | sort -n -k2

Without a certain delimiter it becomes difficult. An attempt to undo the space delimiter:

sed 's/[0-9]\{1,\}/ &/g' testfile | sort -n -k2 | sed 's/ \([0-9]\)/\1/g' 

Hi.

This script uses a sort perl code that in turn uses a perl module Sort::Naturally. That module was not available in my edition of Solaris, but it may be in yours. I copied it from the cpan repository. Note that the guts of the solution is simply calling the perl code with the filename, most of the remainder of the script is supporting code to show data, results, verification, etc. I have added a few lines to illustrate the generality.

Additional information can be found at:
sorting - Perl sort numbers naturally - Stack Overflow
[ Natural Sort ]: Sorting a string with numbers

#!/usr/bin/env bash

# @(#) s1       Demonstrate sorting with embedded numeric strings.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C perl dixf

FILE=${1-data2}
N=${FILE//[A-Za-z]/}
E=expected-output$N

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

pl " Input data file $FILE:"
cat $FILE

pl " Expected output:"
cat $E

pl " Basic perl code:"
cat p3

pl " Results:"
./p3 $FILE |
tee f1

pl " Verify results if possible:"
C=$HOME/bin/pass-fail
[ -f $C ] && $C f1 "$E" || ( pe; pe " Results cannot be verified." ) >&2

pl " Details of p3:"
dixf ./p3

exit 0

producing:

$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: SunOS, 5.11, i86pc
Distribution        : Solaris 11.3 X86
bash GNU bash 4.1.17
perl 5.12.5
dixf (local) 1.54

-----
 Input data file data2:
rpool/swap
rpool/swap14
rpool/swap2
rpool/swap3
a3
a1
a20
a2
a
b25
b2a1
b2a3
b2a2
b1a1

-----
 Expected output:
a
a1
a2
a3
a20
b1a1
b2a1
b2a2
b2a3
b25
rpool/swap
rpool/swap2
rpool/swap3
rpool/swap14

-----
 Basic perl code:
#!/usr/bin/env perl

# @(#) p3       Demonstrate "Natural" sort perl module.

use Sort::Naturally;

my(@data) = <>;
my @sorted = nsort(@data);
print @sorted;

exit(0);

-----
 Results:
a
a1
a2
a3
a20
b1a1
b2a1
b2a2
b2a3
b25
rpool/swap
rpool/swap2
rpool/swap3
rpool/swap14

-----
 Verify results if possible:

-----
 Comparison of 14 created lines with 14 lines of desired results:
 Succeeded -- files (computed) f1 and (standard) expected-output2 have same content.

-----
 Details of p3:
p3      Demonstrate "Natural" sort perl module. (what)
Path    : ./p3
Length  : 11 lines
Type    : executable /usr/bin/env script
Shebang : #!/usr/bin/env perl
Modules : (for perl codes)
 Sort::Naturally        1.03

Best wishes ... cheers, drl

4 Likes

If you can make GNU sort available on Solaris:

sort -V file

Regular sort, for this particular input try:

sort -k1,1.10 -k1.11n 
1 Like

It was not easy to figure it out. Just in case I will leave it here. Thanks
https://www.unix.com/solaris/55835-install-perl-module.html #sudo make install
module Sort::Naturally

1 Like

just a pathetic attempt :slight_smile:

cat prog.sh

#!/bin/bash
file=testfile
echo ------------------
cat $file
while read -r d; do
        echo ${d//[^0-9]} ${d//[^[:alpha:]]} $d
done < $file | sort -k2.1,2.2d -k1,1n | sed 's/.* //'

./prog.sh
rpool/swap
rpool/swap14
rpool/swap2
rpool/swap3
a3
a1
a20
a2
a
b25
b2a1
b2a3
b2a2
b1a1
------------------
a
a1
a2
a3
a20
b1a1
b2a1
b2a2
b2a3
b25
rpool/swap
rpool/swap2
rpool/swap3
rpool/swap14
1 Like

Hi.

Actually, as Scrutinizer wrote, GNU sort may be available, but named as gsort:

$ gsort -V data2
a
a1
a2
a3
a20
b1a1
b2a1
b2a2
b2a3
b25
rpool/swap
rpool/swap2
rpool/swap3
rpool/swap14

in a system like:

OS, ker|rel, machine: SunOS, 5.11, i86pc
Distribution        : Solaris 11.3 X86
gsort sort (GNU coreutils) 8.16

So, always good to have more than one solution ... cheers, drl

2 Likes