#!/usr/local/bin/perl -w # use strict; # Set up the two strings that we want to match and sort to the top # of our list. # our $string1 = shift or die "No strings\n"; our $string2 = shift or die "Only one string\n"; # Print out our data lines sorted using a ST but with an extra map before # the sort to tweak the results of the regular expression match done in # first map. # print map {$_->[0]} # map out original line for print sort { $b->[1] <=> $a->[1] || # elem. 1 is success (1) or failure (0) of # match so descending numeric puts good # lines first $a->[5] <=> $b->[5] || # elem. 5 is our string1/string2 ranking so # ascending numeric gets string1s first $b->[3] <=> $a->[3] || # elem. 3 is two-digit number, highs first $a->[2] cmp $b->[2] || # ascending alpha for string at beginning ... $a->[4] cmp $b->[4] # ... and the one following the digits } map { # If match below succeeded replace elem. 5 of anon. list, which is # either string1 or string2, with a zero if string1 or a one if # string2 so we can do a numeric ascending sort to get all the # string1s and string2s in the right place. # if($_->[1]) { splice @$_, 5, 1, $_->[5] eq $string1 ? 0 : 1; } # Else match did not succeed so replace elems. 2 thru 5, which will # contain undef, with appropriate empty strings or zeros so that the # sort does not complain about "Use of uninitialized value ..." if # warnings are switched on. # else { splice @$_, 2, 4, q(), 0, q(), 0; } # Pass anon. list out of map to sort above. # $_; } map { [ # anon. list constructor $_, # elem. 0 is original line /(?x) # do match with extended syntax ^ # anchor to beginning of line (\S+)\s+ # capture first string, then space(s) (\d\d)\s+ # capture the two digits, then space(s) (\S+)\s+_ # capture string after digits, then space(s) # followed by underscore ($string1|$string2) # capture either string1 or string2 $ # anchor to end of line / ? 1 : 0, # elem. 1 is success or failure of match $1, $2, $3, $4 # elems. 2 thru 5 are our captives ] # close anon. list constructor, list # passed to next map above } ; # Read data a line at a time into first # map of transform above exit; __END__ shirt 47 cotton,white _menswear blouse 88 cotton,pink _womenswear saucepan 82 s/steel,20cm _household singlet 83 cotton,grey _menswear duff_line 56 lots of extra fields so match fails mixer 59 multi_function,dough_hook,blender,black _white_goods skirt 39 tweed,brown _womenswear chefs_knife 11 french_style,8inch _household trousers 27 jean,blue _menswear pepper_mill 51 beech_wood,ceramic _household shirt 15 polyester,lemon _menswear shirt 47 cotton,yellow _menswear duff_line 45 more extra fields so duff again shirt 47 cotton,blue _menswear socks 76 wool,blue,pack_of_5 _menswear microwave 40 850W,turntable,white _white_goods boxers 84 cotton,tartan _menswear trousers 47 cotton,blue _menswear skirt 56 velvet,black_BUT_DUFF_COS_TRAILING_SPACE _womenswear duff_line no_numbers_and_only_one_further_field t-shirt 29 nylon,black _menswear television 83 wide_screen,black _white_goods tie 39 silk,blue _menswear butchers_block 45 beech _household deep_fat_fryer 27 white,non_stick _white_goods blouse 55 silk,bronze_green _womenswear