Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

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
share|improve this question
    
No, -s implies stable sort. You need to show your observation. –  devnull Feb 16 '14 at 8:59
    
What's wrong with the output? What did you expect? –  devnull Feb 16 '14 at 9:02
    
@devnull second column should remain as it is. –  user13107 Feb 16 '14 at 9:03
    
Interchange the first and last lines of your sample file and run the same command. You'll figure. –  devnull Feb 16 '14 at 9:03
    
Why will the second column remain as is? sort sorts lines of input based on the criteria that you provide. –  devnull Feb 16 '14 at 9:04

3 Answers 3

up vote 4 down vote accepted

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
share|improve this answer

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.

share|improve this answer

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
share|improve this answer
    
did not work. It gave me output first column - 1 2 5 1 second column 1 3 4 3 –  user13107 Jun 3 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. –  user1361991 Jun 5 at 0:49
    
@user13107 retested and expanded the answer. –  user1361991 Jun 5 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 Jun 15 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. –  user1361991 Jun 15 at 17:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.