0

I would like to add a new column to an existing matrix in file.txt using awk. I have the file

  -1.664405      -0.019498       0.487501
  -2.210156       0.326547       1.193717
  -2.260318      -0.104277      -0.256821
   2.189078      -2.103898       1.321050
   1.558565      -1.476110       0.967988
   1.764428      -2.955372       1.216211
   ...
   ...

and I would like to have something like this

O     -1.664405      -0.019498       0.487501
H     -2.210156       0.326547       1.193717
H     -2.260318      -0.104277      -0.256821
O      2.189078      -2.103898       1.321050
H      1.558565      -1.476110       0.967988
H      1.764428      -2.955372       1.216211
    ...
    ...

O and H have to vary systematically in this form 100's of times.

Somebody knows how to do it with awk? Thanks in advance

4
  • 3
    You have to explain the difference between O and H, in other words which should be used where. Commented Apr 11, 2021 at 18:41
  • Yes, indeed, thanks by the comment. O's and H's have to vary sistematically as they are:
    – patprovasi
    Commented Apr 11, 2021 at 19:20
  • If "column.txt" is the original file, and "column-new.txt" is the file with the new column, i.e., containing O,H,H, etc., then the command "paste column-new.txt column.txt" would work too - assuming the number of rows of both files are equal. I realize you asked for awk but I'm just trying to provide alternative method. Commented Apr 11, 2021 at 22:23
  • Still not sure what "systematically" means here; at random for each line, with roughly 50% O and 50% H? Commented Apr 15, 2021 at 22:41

3 Answers 3

2

It's not clear to me how much indentation you would like, so I'm assuming just one whitespace between the new first column and the following.

If it has to be awk you might do with:

awk '(NR-1)%3{print "H", $0; next}{print "O", $0}'

Else sed can be used as well:

sed '1~3{s/^/O /p;d};s/^/H /'
1
awk '{ print (FNR-1) % 3 ? "H" : "O", $0 }' file

This uses awk to prefix the current line with an H or an O depending on whether the current line's line number is a multiple of three or not.

If you want a tab character as a delimiter between the new column and the others, make sure that OFS has the value \t:

awk -v OFS='\t' '{ print (FNR-1) % 3 ? "H" : "O", $0 }' file

Using GNU sed specifically and assuming that you want the new column separated from the others with a tab character:

sed -e '1~3 s/^/O\t/' -e '1~3! s/^/H\t/' file

The first expression adds O followed by a tab character to every third line starting at line 1. The second adds H and a tab character to all lines that are not every third line starting at line 1.

This requires GNU sed due to the following two non-standard features:

  1. The address n~m means "every m:th line, starting at line n".
  2. The character sequence \t is expanded to a literal tab character.

Using other tools:

yes 'O H H' | tr ' ' '\n' | head -n "$( wc -l <file )" | paste - file

This produces a steady stream of O, H, H (repeating) on separate lines using yes and tr. This stream is cut short with head to match the number of lines in our file (this is calculated using wc -l). The O:s and H:s are then inserted to the left of the rest of the file's contents using paste, with a tab character as delimiter.

0

It can be done like that:

awk 'BEGIN {chars="OHH"; next_char=1} {print substr(chars, next_char, 1), $0; next_char++} next_char==4 {next_char=1}' matrix

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .