Moving text, side by side after n number of lines

Viewed 123

I am trying to move text side-by-side after a gap in the text.

My example is

684 0.00000 
685 0.00000 
686 0.99490 

684 0.00000 
685 0.00000 
686 0.76000

I would like the text to be as follows

684 0.00000 684 0.00000 
685 0.00000 685 0.00000 
686 0.99490 686 0.76000

I have tried but this hasn't produced the desired output.

awk 'NR%1{printf "%s ",$0;next;}'1 file.txt 

Any help or assistance would be greatly appreciated.

Dan

5 Answers

Using any awk:

$ cat tst.awk
(NR == 1) || !NF {
    numCols++
    numRows = 0
}
NF {
    vals[++numRows,numCols] = $0
}
END {
    for ( rowNr=1; rowNr<=numRows; rowNr++ ) {
        for ( colNr=1; colNr<=numCols; colNr++ ) {
            printf "%s%s", vals[rowNr,colNr], (colNr<numCols ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file
684 0.00000 684 0.00000
685 0.00000 685 0.00000
686 0.99490 686 0.76000
$ pr -2t file

there will be an empty line at the end, which can be trimmed by piping to ... | sed '$d'

Here is another awk that should work with any version of awk:

awk '
!NF {
   n = 0
   next
}
{
   rec[n] = (++n in rec ? rec[n] OFS : "") $0
}
END {
   for (i=1; i<=n; ++i)
      print rec[i]
}' file

684 0.00000  684 0.00000
685 0.00000  685 0.00000
686 0.99490  686 0.76000

One way is to set a column when seeing the empty line, using multidimensional arrays. Something like this:

This is the AWK script, a plain text file. Call it "2col.awk".

BEGIN{
 # -- initialize variables. Recommended.
   column=0
   i=1
}

{
if ($0=="") {    # if line is empty
    column=1     # switch column
    i=1          # reset again
    next         # and move on
  }
  arr[column, i]=$0
  i+=1
}

# -- at the end of file parsing: print it out.
END{
    for (myindex = 1; myindex < i; ++myindex) {
        print arr[0,myindex] "  "  arr[1,myindex]
    }
}

Call the script from command line like this:

awk -f 2col.awk myfilename.ext

where myfilename.ext is the file containing source data.

Given data:

a
b
c

d
e
f

result will be

a b
c d
e f
gawk '! (___+=NR * !NF) ? (__[NR] = $_)*(NF = _) : __[NR-___]==$_ \
          ? $+NF =$_ : ($!NF = __[NR-___] RS $_)^_^sub("[ \t]*[\\\\]?\n"," ")'

684 0.00000 684 0.00000 \
685 0.00000 685 0.00000 \
686 0.99490 686 0.76000

another approach via FS/OFS :

mawk '(____+=NR*!NF) ? (__ = $_) ($_=___[NR-____])($++NF=__)^(__=_) \  
                     : (___[NR] = $_) * (NF = _)'     FS='[\\\\]$' OFS=
Related