Descending order sort for very small numbers - linux

I have my input file as :
Helguson 1.11889675673e-06
CAPTION_spot 1.37407731642e-07
Earning 1.20657023177e-06
340km 6.82228429758e-07
Mortimer 3.08700799033e-07
yellow 6.26784196571e-06
four 0.000271117940104
Pronk 5.79848408861e-07
jihad 3.25632057648e-07
I want to sort in descending order of the second column and hence, I tried using the linux command:
sort -k2 -nr input.txt > output.txt
My output is generated as:
340km 6.82228429758e-07
yellow 6.26784196571e-06
Pronk 5.79848408861e-07
jihad 3.25632057648e-07
Mortimer 3.08700799033e-07
CAPTION_spot 1.37407731642e-07
Earning 1.20657023177e-06
Helguson 1.11889675673e-06
four 0.000271117940104
It is not sorting properly. How to resolve this? Please help.

You need to include the -g option in sort. Otherwise it sorts in alphanumeric order, but with -g it converts it to a number first and then sorts.

Related

unix sort by single column only

I have a file of numbers seperated by comma. I want to sort the list by columns 2 only. my expecation is that lines wil lbe sorted by only the second columns and not by additional columns. I am not looking to sort by multiple keys. I know how to sort by a single key. My question here is why when i am sotin giving start POS and end POS as column 2 why is it also sorting columns 3?
FILE
cat chris.num
1,5,2
1,4,3
1,4,1
1,7,2
1,7,1
AFTER SORT
sort -t',' -k2,2 chris.num
1,4,1
1,4,3
1,5,2
1,7,1
1,7,2
However my expected output is
1,4,3
1,4,1
1,5,2
1,7,2
1,7,1
So i thought since i give the start and end key as -k2,2 that it would sort only based on this column but it seems to be sorting the other columns too. how can i get this to sort only by column 2 and not by others
From the POSIX description of sort:
Except when the -u option is specified, lines that otherwise compare equal shall be ordered as if none of the options -d, -f, -i, -n, or -k were present (but with -r still in effect, if it was specified) and with all bytes in the lines significant to the comparison. The order in which lines that still compare equal are written is unspecified.
So in your case, when two lines have the same value in the second column and thus are equal, the entire lines are then compared to get the final ordering.
GNU sort (And possibly other implementations, but it's not mandated by POSIX) has the -s option for a stable sort where lines with keys that compare equal appear in the same order as in the original, which is what it appears you want:
$ sort -t, -s -k2,2n chris.num
1,4,3
1,4,1
1,5,2
1,7,2
1,7,1

Bash sort -nu results in unexpected behaviour

A colleague of mine noticed some odd behaviour with the sort command today, and I was wondering if anyone knows if the output of this command is intentional or not?
Given the file:
ABC_22
ABC_43
ABC_1
ABC_1
ABC_43
ABC_10
ABC_123
We are looking to sort the file with numeric sort, and also make it unique, so we run:
sort file.txt -nu
The output is:
ABC_22
Now, we know that the numeric sort won't work in this case as the lines don't begin with numbers (and that's fine, this is just part of a larger script), but I would have expected something more along the lines of:
ABC_1
ABC_10
ABC_123
ABC_22
ABC_43
Does anyone know why this isn't the case? The sort acts as one would expect if given just the -u or -n options individually.
With -n, an empty number is zero:
Sort numerically. The number begins each line and consists of optional
blanks, an optional ‘-’ sign, and zero or more digits possibly
separated by thousands separators, optionally followed by a
decimal-point character and zero or more digits. An empty number is
treated as ‘0’.
All these lines have an empty number at the start of the line, so they are all zero for sort's numerical uniqueness. If you'd started each line with the same number, say 1, the effect would be the same. You should specify the field containing the numbers explicitly, or use version sort (-V):
$ sort -Vu foo
ABC_1
ABC_10
ABC_22
ABC_43
ABC_123
You are missing specifying the de-limit on the second field of GNU sort as
sort -nu -t'_' -k2 file
ABC_1
ABC_10
ABC_22
ABC_43
ABC_123
The flag -n for numerical sort, -u for unique lines and the key part is to set de-limiter as _ and sort on the second field after _ done by -k2.

Differences between Unix commands for Sorting CSV

What's the difference between:
!tail -n +2 hits.csv | sort -k 1n -o output.csv
and
!tail -n +2 hits.csv | sort -t "," -k1 -n -k2 > output.csv
?
I'm trying to sort a csv file by first column first, then by the second column, so that lines with the same first column are still together.
It seems like the first one already does that correctly, by first sorting by the field before the first comma, then by the field following the first comma. (breaking ties, that is.)
Or does it not actually do that?
And what does the second command do/mean? (And what's the difference between the two?) There is a significant difference between the two output.csv files when I run the two.
And, finally, which one should I use? (Or are they both wrong?)
See also the answer by #morido for some other pointers, but here's a description of exactly what those two sort invocations do:
sort -k 1n -o output.csv
This assumes that the "fields" in your file are delimited by a transition from non-whitespace to whitespace (i.e. leading whitespace is included in each field, not stripped, as many might expect/assume), and tells sort to order things by a key that starts with the first field and extends to the end of the line, and assumes that the key is formatted as a numeric value. The output is sent explicitly to a specific file.
sort -t "," -k1 -n -k2
This defines the field separator as a comma, and then defines two keys to sort on. The first key again starts at the first field and extends to the end of the line and is lexicographic (dictionary order), not numeric, and the second key, which will be used when values of the first key are identical, starts with the second field and extends to the end of the line, and because of the intervening -n, will be assumed to be numeric data as well. However, because your first key entails the entire line, essentially, the second key is not likely to ever be needed (if the first key of two separate lines is identical, the second key most likely will be too).
Since you didn't provide sample data, it's unknown whether the data in the first two fields is numeric or not, but I suspect you want something like what was suggested in the answer by #morido:
sort -t, -k1,1 -k2,2
or
sort -t, -k1,1n -k2,2n (alternatively sort -t, -n -k1,1 -k2,2)
if the data is numeric.
First off: you want to remove the leading ! from these two commands. In Bash (and probably others since this comes from csh) you are otherwise referencing the last command that contained tail in your history which does not make sense here.
The main difference between your two versions is that in the first case you are not taking the second column into account.
This is how I would do it:
tail -n +2 hits.csv | sort -t "," -n --key=1,1 --key=2,2 > output.csv
-t specifies the field separator
-n turns on numerical sorting order
--key specifies the fields that should be used for sorting (in order of precedence)

sort pipe delimited file with empty columns

I am getting an issue using sort and I believe it is due to an empty column before the column I am sorting on. I ran a sort on the file sort -n -t'|' -k4 testme -o testedsort, here's the output of testedsort
N|N||+006422931|+000359029|OVERLAY
N|N|A|+000000020|+000000000|580
N|N|A|+000000020|+000000020|705
N|N|A|+000008035|+000000000|800
N|N|A|+000009701|+000000000|723
N|N|A.|+000009701|+001569434|742
N|N|A|+000009701|+001569434|742
N|N|A|+000013723|+000000000|DLORGN
N|N|A|+000020963|+000000020|729
N|N|A|+000022110|+004066830|GRANT
It appears that everything is fine except the first record, and the only thing peculiar about it is that we have an empty column. Has anyone seen this and are there any suggestions on how to fix this?
Two things to fix
Assuming you are looking to sort by the fourth field only, specify the sort key as -k4,4
To handle leading + sign in numbers, use -g instead of -n (possibly GNU sort-specific)
sort -k4,4g -t'|' testme -o testedsort

How to sort by two fields (one numeric, one string) at the same time using the built in "sort" program?

I have a file, lets say "bigfile", with tabular data of the following form,
a1 b2 a3 1
b1 a2 c3 0
... and so on.
I want to use the built-in "sort" program on my Linux machine so sort this file by the fourth field(numeric) and then by the first field at the same time. I went through the man pages a couple of times and all I could come up with was,
sort -n -k4,4 -k1,1 bigfile
Is there a way to make "sort" do what I want or I have to write my own custom program?
Thank you.
From the manpage:
POS is F[.C][OPTS], where F is the
field number and C the character
position in the field; both are origin
1. If neither -t nor -b is in effect,
characters in a field are counted from
the beginning of the preceding
whitespace. OPTS is one or more
single-letter ordering options,
which override global ordering options
for that key. If no key is given, use
the entire line as the key.
sort -k4,4n -k1,1 bigfile ought to do it.
Another option would be sort -k1,1 bigfile | sort --stable -n -k4,4 The stable sort means that ties on the 4th field are resolved by the initial position, which is set by the first pass of sort to be first field.

Resources