0

I have a text file "Hessian_h2o_2z.log" containing the following:

            GX1        GY1        GZ1        GX2        GY2         GZ2        GX3        GY3        GZ3
GX1  0.5915206
GY1  0.0139938  0.0135051
GZ1 -0.0876734 -0.0846119  0.5301078
GX2 -0.5223003 -0.0025088  0.0157183  0.5399848
GY2  0.0078178 -0.0011236  0.0070395  0.0007403  0.0012737
GZ2 -0.0489795  0.0070395 -0.0441035 -0.0046382 -0.0079797  0.0499940
GX3 -0.0692203 -0.0114850  0.0719552 -0.0176845 -0.0085581  0.0536178  0.0869048
GY3 -0.0218115 -0.0123815  0.0775724  0.0017685 -0.0001501  0.0009402  0.0200430  0.0125316
GZ3  0.1366530  0.0775724 -0.4860043 -0.0110801  0.0009402 -0.0058905 -0.1255729 -0.0785126  0.4918948

I am trying to sequentially assign each value in the first column of numbers (column 2 in the file) to a variable X, this is what I have so far:

a=1
b=1
a=$((a+1))
b=$((b+1))
X=`awk -v A=$a -v B=$b 'NR == A {print $B}' Hessian_h2o_2z.log`
Y=`awk -v A=$a -v B=$b 'NR == A {print $B}' Hessian_h2o_3z.log`

for var in $X
do
echo $var
done

however this is only producing the output:

0.5915206

Can anyone explain why the loop is not continuing past NR == 2, and column 2?

N.B. relatively new to shell scripting so any help with the script being unnecessarily long for what I am trying to achieve would be appreciated.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • Neither the awk commands nor the loop increment expressions a=$((a+1)), b=$((b+1)) are actually inside your loop – steeldriver Dec 14 '16 at 19:01
  • Is it possible to call upon a variable that you have not yet assigned? – Stephen Mason Dec 14 '16 at 19:02
  • i've just tried moving the variables to within the loop and I am no longer getting any output – Stephen Mason Dec 14 '16 at 19:04
  • 1
    You can't simply move everything inside the loop as it stands, because loop variable $X is unassigned at that point. Really you will need to rethink your whole approach - for example, while read -r x; do echo "$x"; done < <(awk 'NR>1 {print $2}' Hessian_h2o_3z.log) – steeldriver Dec 14 '16 at 19:07
  • 1
    What are you actually trying to do? Why would you assign each value to a shell variable? They're already assigned to an Awk variable ($2). Just use Awk to do whatever you're trying to accomplish. Awk can even call external commands directly if absolutely necessary, but if you're just doing text processing then just use Awk. Currently, it looks like you just want awk 'NR > 1 {print $2}' Hessian_h2o_2z.log but maybe there's more to your needs. – Wildcard Dec 14 '16 at 20:07
  • Basically i have "hessian 1" and "hessian 2" and i am trying to take the value in row 1 column 1 of each hessian, carry out a function using them, and produce a new file, "hessian 3" containing the result, then loop this to do it for all values in the hessian. – Stephen Mason Dec 14 '16 at 20:19

1 Answers1

0

I think, your original approach is flawed. You can do this in pure shell (for small(ish) amounts of (clean) data).

Something along these lines could do the trick for you:

while read -r VarName VarVal junk;
  do eval "$VarName=\"$VarVal\"";
done < /tmp/exampleData;
GX1="GY1"
GX1="0.5915206"
GY1="0.0139938"
GZ1="-0.0876734"
GX2="-0.5223003"
GY2="0.0078178"
GZ2="-0.0489795"
GX3="-0.0692203"
GY3="-0.0218115"
GZ3="0.1366530"

for i in $(cut -f1 -d ' ' /tmp/exampleData );
  do eval "echo $i → $"$i ;
done
cut -f1 -d ' ' /tmp/exampleData 
echo GX1 → $GX1
GX1 → 0.5915206
echo GY1 → $GY1
GY1 → 0.0139938
echo GZ1 → $GZ1
GZ1 → -0.0876734
echo GX2 → $GX2
...