Skip to content Skip to sidebar Skip to footer

Sort A Field In Ascending Order And Delete The First And Last Number

I have a data that looks like following: a 10,5,3,66,50 b 2,10,1,88,5,8,9 c 4,60,10,39,55,22 d 1,604,3,503,235,45,60,7 e 20,59,33,2,6,45,36,34,22 I want to sor

Solution 1:

Here you go:

awk '{l=split($2,a,",");asort(a);printf "%s\t",$1;for(i=2;i<l;i++) printf "%s"(i==l-1?RS:","),a[i]}' t
a       5,10,50
b       2,5,8,9,10
c       10,22,39,55
d       3,7,45,60,235,503
e       6,20,22,33,34,36,45

PS If I remember correct, you need gnu awk due to asort

How it works:

awk '
    {l=split($2,a,",")                      # Split the data into array "a" and set "l" to length of array
    asort(a)                                # Sort the array "a"
    printf "%s\t",$1                        # Print the first column
    for(i=2;i<l;i++)                        # Run a loop from second element to second last element in array "a"
        printf "%s"(i==l-1?RS:","),a[i]     # Print the element separated by "," except for last element, print a new line
    }'  file                                # Read the file

Solution 2:

Well, here is an alternate solution using perl:

$ perl -F'\s+|,' -lane '
print $F[0] . "\t" . join "," , splice @{[sort { $a<=>$b } @F[1..$#F]]} , 1, $#F-2' file
a       5,10,50
b       2,5,8,9,10
c       10,22,39,55
d       3,7,45,60,235,503
e       6,20,22,33,34,36,45

or with newer versions of perl you can drop the @{..} and say:

perl -F'\s+|,' -lane '
    print $F[0] . "\t" . join "," , splice [sort { $a<=>$b } @F[1..$#F]] , 1, $#F-2
' file

or just use sub-script:

perl -F'\s+|,' -lane '
    print $F[0] . "\t" . join "," , ( sort { $a<=>$b }@F[1..$#F] ) [1..$#F-2]
' file

Solution 3:

Python:

with open('the_file.txt', 'r') as fin, open('result.txt', 'w') as fout:
    for line in fin:
        f0, f1 = line.split() 
        fout.write('%s\t%s\n' % (f0, ','.join(sorted(f1.split(','), key=int)[1:-1])))

The body of the loop can be unpacked as:

        f0, f1 = line.split()           # split fields on whitespace
        items = f1.split(',')           # split second field on commas
        items = sorted(items, key=int)  # or items.sort(key=int) # sorts items as int
        items = items[1:-1]             # get rid of first and last items
        f1 = ','.join(items)            # reassemble field as csv
        line = '%s\t%s\n' % (f0, f1)    # reassemble line
        fout.write(line)                # write it out

Solution 4:

Full python example. This assumes your data is in a text file. You would call it like this.

./parser.py filename

Or you could pipe it together like this:

echo 'a    3,2,1,4,5' | ./parser.py -

Code:

#!/bin/env python
import argparse
import sys

def splitAndTrim(d):
    line = str.split(d)
    arr = sorted(map(int, line[1].split(',')))
    print("{0}    {1}".format(line[0], ",".join(map(str, arr[1:-1]))))


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('FILE', type=argparse.FileType('r'), default=sys.stdin)
    args = parser.parse_args(sys.argv[1:])
    for line in args.FILE:
        splitAndTrim(line)

Post a Comment for "Sort A Field In Ascending Order And Delete The First And Last Number"