0

I have a string "abc" and I am greping it in 15 files in my directory in shell. When I grep "abc" in my 15 files than it returns me the whole line of the files in which its present like this:

abc 0.2 9.0 abc 0.01 8.0 abc 0.06 9.4 abc 0.02 8.7 

Now I want this output to be sorted in ascending order according to the second column.

So I wrote the command like this:

grep "abc" *.txt | sort -nr -t_ -k2 

but the above command is not working and I don't know why.

4 Answers 4

3

Your command is not working because you don't have underscores separating the columns; further, you wanted the data ascending but you told it to sort in reverse (descending) order. Use:

grep "abc" *.txt | sort -n -k 2 

Or:

grep "abc" *.txt | sort -k 2n 

Note that if there are multiple files, your grep output will be prefixed with a file name. You will have to decide whether that matters. It only screws things up if there are spaces in any of the file names. The -h option to grep suppresses the file names.

Sign up to request clarification or add additional context in comments.

Comments

2

I suggest to delete -t_ parameter, because as I see you use spaces as separator, not underscore. After that it works for me:

$ cat t | sort -n -k2 abc 0.01 8.0 abc 0.02 8.7 abc 0.06 9.4 abc 0.2 9.0 

Updated: and yes, as @jonathan-leffler said you also should omit -r option for sorting in ascending order.

Comments

1

You can replace your entire script, including the call to grep, with one call to awk

awk '/abc/{a[$2,i++]=$0}END{l=asorti(a,b);for(i=1;i<=l;i++)print a[b[i]]}' *.txt 

Example

$ ls *.txt four.txt one.txt three.txt two.txt $ cat *.txt abc 0.02 8.3 foo abc 0.06 9.4 bar blah blah abc 0.2 9.0 blah abc 0.01 8.0 blah abc 0.02 8.7 blah blah $ awk '/abc/{a[$2,i++]=$0}END{l=asorti(a,b);for(i=1;i<=l;i++)print a[b[i]]}' *.txt abc 0.01 8.0 abc 0.02 8.3 abc 0.02 8.7 abc 0.06 9.4 abc 0.2 9.0 

2 Comments

(1) asorti() is a GNU awk extension; since the question is tagged Linux, this is not a major issue. (2) The assignment a[$2] = $0 means that you are only saving unique values from the second column, not all lines that match.
@JonathanLeffler Thanks. Good catch on the a[$2], fixed.
0

First problem: you've used -t_ to specify the field separator, but the output doesn't contain _ characters.

Next problem: the -k option has two arguments, start field and end field. By omitting the end field, you get end_of_line by default.

I'd suggest writing it like this:

grep "abc" *.txt | sort -nr -k2,2 

4 Comments

You can use -k2 as a shorthand for -k2,2. The man page says: _ -k, --key=POS1[,POS2] start a key at POS1, end it at POS2 (origin 1)_.
That's not correct, sorry. Quoting the full coreutils manual, -k means "Specify a sort field that consists of the part of the line between POS1 and POS2 (or the end of the line, if POS2 is omitted)".
And you are going to spot the difference...how?
Because it changes the sort key to span multiple fields in ways you probably didn't intend. Please see the comments to example sort -t : -k 2,2n -k 5.3,5.4 here: gnu.org/software/coreutils/manual/coreutils#sort-invocation

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.