Data rearranging from rows to column

Hello Everyone,

I have a input file looks like

-0.005-0.004-0.003-0.002-0.00100.0010.0020.0030.0040.005

My desired output should look like

-0.005
-0.004
-0.003
-0.002
-0.001
0
0.001
0.002
0.003
0.004
0.005

I had some success in getting the desired output. But i face a problem when i try to write the numbers from

-0.00100.001

. I always get the output such as

-0.005
-0.004
-0.003
-0.002
-0.0010
0.001
0.002
0.003
0.004
0.005

without the 0 inbetween -0.001 and 0.001

I would really glad if anyone can help me out in this.

Thanks

Hello dinesh.n,

Could you please check if following may help you. As per shown input I have prepared if there are more conditions are there then kindly let me know.

awk --re-interval '{gsub(/^\-[0]\.[0-9]{3}/,"&\n",$0);gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);A=$0} END{gsub(/00\./,"0\n0.",A);gsub(/\n\n/,"\n",A);print A}' Input_file
 

Output will be as follows.

-0.005
-0.004
-0.003
-0.002
-0.001
0
0.001
0.002
0.003
0.004
0.005
 

Thanks,
R. Singh

1 Like

Hello R. Singh,

Thanks for your reply

Hello R. Sing,

Please have a look at my original input file(U_z1) and my output file (U_z17)

Thanks

Hello Dinesh,

A little change as per your input file's format has done the trick, could you please check it and let me know if All is Well.

 awk --re-interval '{gsub(/-[0]\.[0-9]{2,3}/,"&\n",$0);gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);A=A?A ORS $0:$0} END{gsub("\n\n","\n",A);print A}'  Input_file
 

Not pasting output as it is huge is in size.
EDIT: Adding a non one liner form of solution now.

awk --re-interval '{
                        gsub(/-[0]\.[0-9]{2,3}/,"&\n",$0);
                        gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);
                        A=A?A ORS $0:$0
                   }
                        END{
                                gsub("\n\n","\n",A);
                                print A
                   }
                  ' Input_file
 

Also want to add here your initial input was not having in between proper 0s in positive values so made a slight change in that.

Thanks,
R. Singh

1 Like

Hello R. Singh,

Please find the output file. The output is from the first code you posted.

awk --re-interval '{gsub(/^\-[0]\.[0-9]{3}/,"&\n",$0);gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);A=$0} END{gsub(/00\./,"0\n0.",A);gsub(/\n\n/,"\n",A);print A}' Input_file

Looks like some values are still not sorted out. Could you please help me in this. The other code doesn't work properly.

Thanks
Dinesh.N

Hello Dinesh,

Could you please try following and let me know if this helps.

 cat check_match.ksh
 awk --re-interval '{gsub(/-[0]\.[0-9]{2,3}/,"&\n",$0);gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);A=A?A ORS $0:$0} END{gsub("\n\n","\n",A);print A}' Input > temp_out
awk '{B=$0;A=gsub(/\./,X,B);if(A==2){C=$0;match(C,/.*\./);gsub(/\..*\./,"0.",$0);print "0" substr(C,RSTART,RLENGTH-1) ORS $0} else {print $0}}' temp_out
 

NOTE: You need to run the script named check_match.ksh, with giving proper permissions to it.

Thanks,
R. Singh

1 Like

Hello R. Singh,

I tried the code you gave me.

 
cat check_match.ksh
 awk --re-interval '{gsub(/-[0]\.[0-9]{2,3}/,"&\n",$0);gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);A=A?A ORS $0:$0} END{gsub("\n\n","\n",A);print A}' Input > temp_out
awk '{B=$0;A=gsub(/\./,X,B);if(A==2){C=$0;match(C,/.*\./);gsub(/\..*\./,"0.",$0);print "0" substr(C,RSTART,RLENGTH-1) ORS $0} else {print $0}}' temp_out

It seems to be working, but in some line there are this 0 and -0 added at the front and back of some values. Please check the output file for reference

Thanks,
Dinesh.N

Try also

sed -r 's/(-*[0-9]\.)/\n\1/g; s/(\.[0-9]{3})([0-9])/\1\n\2/g; s/\n//' /tmp/U_z1.txt

This doesn't work if the number in front of the single 0 has less than 3 decimals.

1 Like

Hello Dinesh,

As you haven't mentioned how many zeros you need after point, so following code will take 3 zeros after point, let me know if this helps you.

cat check_match.ksh
awk --re-interval '{gsub(/-[0]\.[0-9]{2,3}/,"&\n",$0);gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);A=A?A ORS $0:$0} END{gsub("\n\n","\n",A);print A}' Input_file > out1221
awk '{B=$0;A=gsub(/\./,X,B);if(A==2){C=$0;match(C,/.*\./);gsub(/\..*\./,"0.",$0);R=substr(C,RSTART,RLENGTH-1) ORS $0;if(R !~ /^0/){Q="0" R;print substr(Q,1,5);} else {print $0}} else {print $0}}' out1221
 

EDIT: Adding a non one-liner form for solution now.

cat check_match.ksh
awk --re-interval '{gsub(/-[0]\.[0-9]{2,3}/,"&\n",$0);
                    gsub(/[0]{1,2}\.[0-9]{3}/,"&\n",$0);
                    A=A?A ORS $0:$0
                   }
                    END{
                                gsub("\n\n","\n",A);
                                print A
                       }
                   ' Input > out1221
awk '{B=$0;
      A=gsub(/\./,X,B);
                        if(A==2){C=$0;
                                 match(C,/.*\./);
                                 gsub(/\..*\./,"0.",$0);
                                 R=substr(C,RSTART,RLENGTH-1) ORS $0;
                                                if(R !~ /^0/){Q="0" R;print substr(Q,1,5);
                                                             }
                                                else {print $0}
                                }
                        else {print $0}
      }
    ' out1221
 

Thanks,
R. Singh

1 Like

Good morning everyone,

Thanks for all your effort for helping me out. I now face a problem with a differnt data structure. Where some part of my values contains many zeros and i need them to be arranged in a seperate zeros. such as

-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001

. Where my output should look like

-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001

I used the previous codes from RudiC and R.Singh and good a output(U_z27), please check the attachment. My input file is U_z2.

Thanks
Dinesh.N

Can't be done reliably unless further info is supplied, e.g. number of zeroes.

1 Like

Hello RudiC,

Thanks for your reply. Actually the problem is it's not possible to tell how many zeros. I am trying to automize the post processing based on the results genetrated by a CFD tool and in my future case there might be many hundres of zeros. If you could please check the outpout file U_z27 with input coming from U_z2. I used your code

sed -r 's/(-*[0-9]\.)/\n\1/g; s/(\.[0-9]{3})([0-9])/\1\n\2/g; s/\n//'

and got this output. The results looks fine but it is not arranging the zeros ( from line 2927 in the output file). I know that i might still not able to clarify your question. But if you could still help me. I will be glad.

Note: Files U_z2 and U_z27 are in my previous post

Thanks
Dinesh.N

Hello Dinesh,

Could you please try following script and let me know if this helps you.
Let's say input file is as follows.

cat Input_file
-0.001-0.001-0.001-0.001-0.0010000000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001-0.001-0.001-0.001-0.001-0.00100000.0010.0010.0010.001

Then following is the code for same.

cat get_output.ksh
awk --re-interval '{gsub(/0\.00[0-9]/,"&\n");gsub(/000+/,"&\n0");print}' Input_file > output1
awk '{if($0 ~ /^0+$/){split($0, array,"");j=length(array);for(i=1;i<j;i++){print array}} else {print}}' output1

Output will be as follows.

-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001
-0.001
-0.001
-0.001
-0.001
-0.001
0
0
0
0
0.001
0.001
0.001
0.001

Hope this helps you.

EDIT: Changed the script into code by reading directly Input_file without writing awk 2 times now.

awk --re-interval '{gsub(/0\.00[0-9]/,"&\n");gsub(/000+/,"&\n0")split($0, A,"\n");} END{q=length(A);for(i=1;i<=q;i++){if(A ~ /^0+$/){split(A, array,"");for(u=1;u<=length(A)-1;u++){print array}} else {print A}}}'  Input_file
 

Non one-liner form of solution.

awk --re-interval '{
                        gsub(/0\.00[0-9]/,"&\n");
                        gsub(/000+/,"&\n0");
                        split($0, A,"\n");
                   }
                        END{
                                q=length(A);
                                for(i=1;i<=q;i++){
                                                        if(A ~ /^0+$/){
                                                                                split(A, array,"");
                                                                                for(u=1;u<=length(A)-1;u++){
                                                                                                                print array
                                                                                                              }
                                                                         }
                                                        else             {
                                                                                print A
                                                                         }
                                                 }
                           }
                  ' Input_file
 

Thanks,
R. Singh

1 Like

If there's no info, we need to base solutions on assumptions. This one assumes that there's no trailing zeroes in a value, i.e. a less than three decimal number ends witha meaningful digit, and that there's positive values to follow the zeroes' suite. Try

sed -r 's/(-*[0-9]\.)/\n\1/g; :L; s/([^\n])0\n/\1\n0\n/;tL; s/\n//' /tmp/U_z2.txt
1 Like

Hello R.Singh,

Thanks for the code. I works absolutely fine. Keep up the good work. :b:

Thanks,
Diensh.N

---------- Post updated at 02:03 PM ---------- Previous update was at 01:41 PM ----------

Hello RudiC,

Thank you . Your code works as well.

Thanks,
Dinesh.N

1 Like