Sort each row (horizontally) in AWK or any

Hello,

How to sort each row in a document with numerical values and with more than one row. Example

Input data (file1.txt):
4 6 8 1 7
2 12 9 6 10
6 1 14 5 7

and I want the the output to look like this(file2.txt):
1 4 6 7 8
2 6 9 10 12
1 5 6 7 14

I've tried

 sort -n file1.txt > file2.txt

also

 sort -k5n,5 file1.txt > file2.txt

and

awk '{split($0,a);asort(a);for(i=NF;i>0;i--){printf("%s ",a)}print ""}' file1.txt > file2.txt

but these don't work.

Thank you.

You were close with the awk:

awk ' {split( $0, a, " " ); asort( a ); for( i = 1; i <= length(a); i++ ) printf( "%s ", a ); printf( "\n" ); }' input >output

Some versions of awk have a buggy asort() function. Off the top of my head I don't remember the circumstanses, but for anything that counts I write my own sort function.

Hello,

Thanks agama, but
this is the message I get after executing the code

awk: calling undefined function asort
 input record number 1, file test.txt
 source line number 1

Then your awk is not gnu awk and thus doesn't have asort().

Try this:

awk '
        # sort v1 into ascending order
        function bubble( v1,            n, s, i, pass, swap )
        {
                swap = 1;
                pass = 0;

                while( swap )
                {
                        swap = 0;
                        pass++;
                        for( i = 0; i <  n - pass;  i++ )
                        {
                                if( v1 > v1[i+1] )
                                {
                                        swap++;
                                        s = v1;
                                        v1 = v1[i+1];
                                        v1[i+1] = s;
                                }
                        }

                }
        }

    {
        split( $0, a, " " );    
        bubble( a ); 
        for( i = 1; i <= length(a); i++ ) 
            printf( "%s ", a ); printf( "\n" ); 
    }'  input >output

It uses a simple bubble sort -- not all that efficient, but it works.

[root@node2 ~]# cat sort.sh 
while read line; do
      ary=(${line})
      for((i=0; i!=${#ary[@]}; ++i)); do
         for((j=i+1; j!=${#ary[@]}; ++j)); do
              if (( ary > ary[j] )); then
                    ((key=ary))
                    ((ary=ary[j]))
                    ((ary[j]=key))
              fi
         done
      done
      echo ${ary[@]}
done < ${1}
[root@node2 ~]# cat data 
4 6 8 1 7
2 12 9 6 10
6 1 14 5 7
[root@node2 ~]# bash sort.sh data 
1 4 6 7 8
2 6 9 10 12
1 5 6 7 14
1 Like

For agama

I tried this

 awk -f code.awk file1.txt > file2.txt

and gave me this

awk: can't open file code.awk
 source line number 1 source file code.awk
 context is
	 >>>  <<< 

I'm not an expert and I'll figure it out if I can, or any advice you can give me? I'll appreciate it. I'll try to install the GNU awk and make the previous code work.

thanks.

For huaihaizi3
Sorry, I'm not an expert and I currently don't know how to run that code you posted, I will definitely research and find out what you mean. I was basically looking for an awk code or a unix command that would do the job. That looks like C, I will work on your code to understand it better and see if I can make it work. I appreciate your help, any advice?

From the looks of things you didn't name the file code.awk. If you run the command ls -al code.awk what do you get? The fact that awk says it cannot open the file means that the file isn't in the current directory.

As for running the other code... edit a file (we'll call it foo.sh just to have something specific) and paste the code into it. Then you can set the execute bit with chmod 755 foo.sh and can run it as a command by typing foo.sh xxx.txt on the command line.

You can do the same with the awk as long as you leave the leading awk ' and trailing close quote.

1 Like

@joseamck
just run the script sort.sh with your file, such as:

bash sort.sh your_file
1 Like

Or just blow your own bubbles... :wink:

awk '{c=1;while(c!=""){c=""; for(i=1;i<NF;i++){n=i+1; if($i>$n){c=$i;$i=$n;$n=c}}}}1' infile
2 Likes

Hi.

See http://www.unix.com/shell-programming-scripting/112379-sort-words-line.html for a number of techniques (some similar those posted here). In the cases that use the command sort, you will need to specify a numeric sort instead of the default character sort.

Best wishes ... cheers, drl

perl -lane '$,=" "; print sort { $a <=> $b } @F' infile
2 Likes

Hi.

A slightly different solution in perl:

#!/usr/bin/env bash

# @(#) s1	Demonstrate sort numeric items on a line, perl.

pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C perl

pl " Input data file data1:"
cat data1

pl " Results of single line (cryptic) perl:"
perl -wn -e 'print join(" ",sort({$a<=>$b} split())),"\n";' data1

exit 0

producing:

% ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0.8 (lenny) 
bash GNU bash 3.2.39
perl 5.10.0

-----
 Input data file data1:
4 6 8 1 7
2 12 9 6 10
6 1 14 5 7

-----
 Results of single line (cryptic) perl:
1 4 6 7 8
2 6 9 10 12
1 5 6 7 14

I like Scutinizer's solution. It illustrates useful features of perl that are similar to awk features. One does not see them often.
Best wishes ... cheers, drl

( Edit 1: simultaneous post with Scrutinizer )

1 Like

Thank you,

I learned something today, thank you all. It works.