Awk: is it possible to print into multiple columns?

Hi guys,

I have hundreds file like this, here I only show two of them:
file 1

feco4_s_BB95.log                                    ZE_1=-1717.5206260
feco4_t_BB95.log                                    ZE_1=-1717.5169250
feco5_s_BB95.log                                    ZE_1=-1830.9322060

file 2

feco4_s_BBRC.log                                    ZE_1=-1717.2394670
feco4_t_BBRC.log                                    ZE_1=-1717.2382150
feco5_s_BBRC.log                                    ZE_1=-1830.6170990

can I get an output like this? which is simple for copying into excel.

feco4_s_BB95.log        -1717.5206260 -1717.2394670
feco4_t_BB95.log        -1717.5169250 -1717.2382150
feco5_s_BB95.log        -1830.9322060 -1830.6170990

Thank you very much for your kind help!

Zhen

The order of results is not guaranteed:

{ sub(/ZE_1=/,""); A[$1]=A[$1]" "$2 } END { for(X in A) print X, substr(A[X],1) }' inputfile

Thanks. But the order should consistent with the file name, let say the second column should be the numbers from the file2, and so the hundredth column should be from the file100. ortherwise, these numbers are not in order and are becoming meaningless.

could it possibly be processed with cycles?

Are your first column always the same and in same order?
If yes, this might help extract col2 from all your files , but you need to paste col1 from one of your files.

Should maintain order.

BEGIN {
  count = 1
}

FNR == 1 && FNR < NR {
  count++
}

{
  if ( _[FNR] ) {
    while ( c[FNR] != count-1 ) {
      _[FNR] = (_[FNR] " " sprintf("%8s",""))
      c[FNR]++
    }
    _[FNR] = (_[FNR] " " sprintf("%-8s",$2))
    c[FNR]++
  }
  else if ( count == 1 ) {
    _[FNR] = sprintf("%-8s",$2)
    c[FNR]++
  }
  else {
    while ( c[FNR] != count-1 ) {
      if ( _[FNR] )
        _[FNR] = (_[FNR] " " sprintf("%8s",""))
      else
        _[FNR] = sprintf("%8s","")
      c[FNR]++
    }
    _[FNR] = (_[FNR] " " sprintf("%-8s",$2))
    c[FNR]++
  }
}

END {
  for (i=1; i<=length(_); i++)
    print _
}

Save this as liuzhencc.awk , give a execute status like chmod 777

and run as

awk -f liuzhencc.awk file1 file2 .... filen 

Are they sorted, and guaranteed not missing any rows? You could just use paste.

I think it works with the following code, but in very an inefficient way.

/*add the file name to the first row*/
for i in file*; do
printf "%20s" ${i} >> $i.txt;
done

printf "\n" >> ../$i.txt;

/*print the numbers of the second row from each file $i*/
for ((j=1;j<=11;j++)); do
for i in file*; do
Num=$(awk "NR==${j}" ${i} | awk -F= '{print $2}');
printf "%20.7f" "${Num}" >> $i.txt;
done;

printf "\n" >> $i.txt;

done;

Are they sorted, and guaranteed not missing any rows? You could just use paste.

I cannot get it work in bash. the error message:

-bash: syntax error near unexpected token `/ZE_1=/,""'

My program, on reflection, isn't even close to what you want anyway.

paste might be closer, if your data is all in the same order and guaranteed not missing any rows.

Is it?

Please answer my question. It's relevant.

1 Like

yes. the data for all formatted in same order and not missing any rows and any column.
Sorry for my bad English and I didn't read the question.
will it be possible to give an output as below?

                                         file1                   file2
feco4_s_BB95.log        -1717.5206260 -1717.2394670
feco4_t_BB95.log        -1717.5169250 -1717.2382150
feco5_s_BB95.log        -1830.9322060 -1830.6170990

I will do this in 3 steps.

  1. Extracting the first column from any of the files, add a blank line and store in a file.
awk 'NR==1{print ""} {print $1}'  file1 > ../tmpcol1
  1. Paste all col2 side by side from all files with file-names as headers.
awk '
            FNR == 1 {
                    c += 1
                    d = FILENAME
                    sub ( /\/.*/, X, d )
                    D[c] = d
            }
            {
                    A[c,FNR] = $2
                    m = m < FNR ? FNR : m
            }
            END {
                    while ( ++k <= c )
                            printf "%s\t", D[k]
                    printf "\n"
    
                    while ( ++j <= m )
                    {
                            while ( ++i <= c )
                            {
                                    printf "%s\t", A[i,j]
                            }
                            printf "\n"
                            i = 0
                    }
            }
'  * > allcol2
  1. Paste the 1st column from step 1 and delete it.
paste ../tmpcol1 allcol2 > final_file
rm ../tmpcol1
1 Like

Thanks! it does the trick!

---------- Post updated at 02:26 AM ---------- Previous update was at 02:19 AM ----------

Thanks Corona688! yes, "Paste" also does the trick very effectively. This functional is exactly what I expected at the very beginning, which could paste the column from multiple files into a table sheet. However, I didn't know there is a command like "Paste". Now, everything become simple. Thanks again for your help!