6

How to (numerically) sort a specific column in a text file, without affecting other columns (irrespective of whether they are sorted or unsorted)? On other threads I found -s argument, but it does sort other columns.

Observation

$ cat tmp.txt
1 1
2 3
5 4
1 3

$ sort -s -n -k1,1 tmp.txt
1 1
1 3
2 3
5 4
7
  • No, -s implies stable sort. You need to show your observation.
    – devnull
    Commented Feb 16, 2014 at 8:59
  • What's wrong with the output? What did you expect?
    – devnull
    Commented Feb 16, 2014 at 9:02
  • @devnull second column should remain as it is.
    – user13107
    Commented Feb 16, 2014 at 9:03
  • Interchange the first and last lines of your sample file and run the same command. You'll figure.
    – devnull
    Commented Feb 16, 2014 at 9:03
  • Why will the second column remain as is? sort sorts lines of input based on the criteria that you provide.
    – devnull
    Commented Feb 16, 2014 at 9:04

3 Answers 3

6

As mentioned in the comments, you can't achieve what you want using sort alone.

You could cut the input file, feed relevant part to sort, and paste those.

$ paste -d' ' <(cut -d' ' -f1 input | sort -n) <(cut -d' ' -f2- input)
1 1
1 3
2 4
5 3
0
1

A solution in perl:

perl -lane '
 push @first , $F[0];
 push @second, $F[1];
 END{
    @first = sort { $a <=> $b } @first;
    print "$fist[$_] $second[$_]" for (0..$#first)
 }' your_file

It assumes the first column (the one to be sorted) consists only of numerical data.

0

I'm on solaris and needed an answer without sort -s and the accepted answer wasn't working for me. Joeyg on unix.com had the answer: sort-one-column-only

cat tmp.txt
1 5
2 3
5 4
1 3

#Sort by 1st column leaving second stable sorted by the 1st.
cat -n tmp.txt | sort -k 2,2 | awk '{print $2,$3}'
1 5
1 3
2 3
5 4

#Sort by 2nd column leaving first stable sorted by the 2nd.
cat -n tmp.txt | sort -k 3,3 | awk '{print $2,$3}'
2 3
1 3
5 4
1 5

Different interpretation via comment is to sort a single column without affecting the rest:

#Sort by 1st column leaving other columns untouched:
cat -n tmp.txt | sort -k 2,2 | awk '{a[NR]=$2;b[$1]=$3} END {for (i=1;i<=NR;i++)print a[i]" "b[i]}'
1 5
1 3
2 4
5 3

Explanation:
cat -n adds rownums to force sort to do "sort -s" without GNU sort.
sort -k 2,2 sorts by the 1st column

NR is a built-in variable that holds the row num.
a[NR]=$2; puts the sorted column in a[1..4]
b[$1]=$3; puts the "unsorted" 2nd column in b[rownum from cat]
Then the for loop just outputs the two arrays.

What I needed which was the newest unique column 3 entries in the file. e.g.

cat tmp2.txt
5|1|3
4|2|1
1|3|2
3|4|1
2|5|2

cat -n tmp2.txt | sort -k 3 -rut '|' | awk '{print $2}'
5|1|3
2|5|2
3|4|1
6
  • did not work. It gave me output first column - 1 2 5 1 second column 1 3 4 3
    – user13107
    Commented Jun 3, 2015 at 23:25
  • @user13107 did you try running the first block cat -n tmp | sort -k 2,2 | awk '{print $2,$3}' ? The trick is in cat -n. Which outputs line numbers before the sort. Will retest tomorrow.
    – DKATyler
    Commented Jun 5, 2015 at 0:49
  • @user13107 retested and expanded the answer.
    – DKATyler
    Commented Jun 5, 2015 at 18:03
  • your first column is not unchanged in first example. it's 2 1 5 1 in the end and it was 1 2 5 1 initially.
    – user13107
    Commented Jun 15, 2015 at 4:31
  • @user13107 I think I understand the question now. You may wish to edit your original question to give an example of what you wanted. I had assumed you wanted a stable sort that left other columns in their original order relative to the new sort.
    – DKATyler
    Commented Jun 15, 2015 at 17:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .