3

I have this file:

100: pattern1
++++++++++++++++++++
1:pattern2
9:pattern2
+++++++++++++++++++
79: pattern1
61: pattern1
+++++++++++++++++++

and I want to sort it like this:

++++++++++++++++++++
1:pattern2
9:pattern2
+++++++++++++++++++
61:pattern1
79:pattern1
100:pattern1
+++++++++++++++++++

Is it possible using Linux sort command only ?

If I had :

4:pat1 
3:pat2
2:pat2
1:pat1

O/p should be:

1:pat1
++++++++++++ 
2:pat2
3:pat2
++++++++++++
4:pat1

So, want to sort on first group, but "group" on the pattern of second group. Please note, the thing after : is a regex pattern not a literal.

4
  • What is the criteria for the first and second group? Commented May 28, 2011 at 18:24
  • 1
    I understand that you are trying to group lines depending on what comes after ':', and output a separator line between groups, but I do not understand how you want groups to be sorted. Are you assuming that the range of numerical values before ':' will never overlap between groups? That is, if you have "1:a", "2:b", "3:b" and "4:a", do you want to get the "a"s first or the "b"s first? Commented May 28, 2011 at 18:58
  • why the 1st 100 comes into second group? What are the sorting criteria? By the text following the number? so "1000:wow" will come into 1st group and "1:this is it" into second? Commented May 28, 2011 at 19:03
  • 1
    It seems like you'd be better off inserting the ++++s yourself after walking through each line after a sort and you see that the value after : has changed. Commented May 28, 2011 at 20:15

4 Answers 4

1

Best you can do is to sort it according to the numerical values. But you cannot do anything with the "+"-string.

$ sort -n input
+++++++++++++++++++
+++++++++++++++++++
++++++++++++++++++++
1:wow
9:wow
61: this is it
79: this is it
100: this is it
Sign up to request clarification or add additional context in comments.

Comments

0

I don't believe sort alone can do what you need.

Create a new shell script and put this in its contents (ie mysort.sh):

#!/bin/sh
IFS=$'\n' # This makes the for loop below split on newline instead of whitespace.
delim=+++++++++++++++++++
for l in `grep -v ^+| sort -g`      # Ignore all + lines and sort by number
do
    current=`echo $l | sed s/^[0-9]*://g` # Get what comes after the number
    if [ ! -z "$prev" ] && [ "$prev" != "$current" ] # If it has changed...
    then                                  #  then output a ++++ delimiter line.
        echo $delim
    fi
    prev=$current
    echo $l                               # Output this line.
done

To use it, pipe in the contents of your file like so:

cat input | sh mysort.sh

Comments

0

Probably not -- it's not in the sort of format sort(1) expects. And if you did it would be one of those amazing hacks, not easily used. If you have some sort of rule for what goes between the lines of plus signs, you can do it readily enough with an AWK or Perl or Python script.

Comments

0

If your input was space delimited, not ':' delimited:

sort  -rk2 | uniq -D -f1

will do the grouping;

  • I guess you'd need to sort the 'subsections' later (unfortunately my sort(1) doesn't do composite key ordering. I do believe there are version that allow you to do sort -k2,1n and you'd be done at once).
  • use --all-repeated=separate instead of -D to get blank separators between groups. Look at man uniq for more ideas!

However, since your input is colon delimited, a hack is required:

sed 's/\([0123456789]\+\):/\1 /' t | sort  -rk2 | uniq -D -f1

HTH

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.