4

I have a file with three columns (ID number, x, y)

ifile.txt
1      32.2    21.4
4      33.2    43.5
5      21.3    45.6
12     22.3    32.5
32     21.5    56.3
43     33.4    23.4
44     23.3    22.3
55     22.5    32.4

I would like to make a loop over column 2 and 3 so that is will read like

for x=32.2 and y=21.4; do execute a fortran program
for x=33.2 and y=43.5; do execute the same program
and so on

Though my following script is working, but I need it in an efficient way.

s1=1   #serial number
s2=$(wc -l < ifile.txt)   #total number to be loop
while [ $s1 -le $s2 ]
do
x=$(awk 'NR=='$s1' {print $2}' ifile.txt)
y=$(awk 'NR=='$s1' {print $3}' ifile.txt)
cat << EOF > myprog.f
...
take value of x and y
...
EOF
ifort myprog.f
./a.out
(( s1++ ))
done

Kindly Note: myprog.f is written within a cat program. for example,

cat << EOF > myprog.f
....
....
take value of x and y
....
....
EOF
7
  • How does xyz relate to shell variables $x and $y, and if xy refers to these shell variables, what does z refer to? Commented Apr 25, 2016 at 3:19
  • Sorry for the confusion. No, here xy does not refer those variables. I have changed it. Thank you. Commented Apr 25, 2016 at 3:35
  • So you expect $x and $y to be environment variables that myprog.f will be able to read? Is $s1 of relevance, or is it only used to drive the loop? Commented Apr 25, 2016 at 3:37
  • yes, $s1 is not important here. It is used only to drive the loop. Commented Apr 25, 2016 at 3:46
  • Does your update mean you're (re-)writing your Fortran program's source code in each iteration of the loop, compiling it with ifort, and then executing it? Why would you not statically compile a program that takes arguments? Commented Apr 25, 2016 at 3:47

2 Answers 2

6

Simple way to read a file in bash is

while read -r _ x y; do
    echo "x is $x, y is $y"
    # your Fortran code execution
done < ifile.txt
x is 32.2, y is 21.4
x is 33.2, y is 43.5
x is 21.3, y is 45.6
x is 22.3, y is 32.5
x is 21.5, y is 56.3
x is 33.4, y is 23.4
x is 23.3, y is 22.3
x is 22.5, y is 32.4
Sign up to request clarification or add additional context in comments.

Comments

2

It looks like you're trying to create Fortran source code in each loop iteration with the loop variables baked into the source code, compiling it, and then invoking it, which is quite inefficient.

Instead, you should create a Fortan program once, and have it accept arguments.
(I don't know Fortran, and you haven't stated a specific compiler, but perhaps this GNU Fortran documentation will get you started.)

Assuming you have such a program and its path is ./a.out, you can invoke awk combined with xargs as follows, passing the 2nd ($2) and 3rd ($3) fields as arguments:

awk '{ print $2, $3 }' file | xargs -n 2 ./a.out
  • awk '{ print $2, $3 }' prints the 2nd and 3rd whitespace-separated field from each input line, separated by a space.

  • xargs -n 2 takes pairs of values from awk's output and invokes ./a.out with each pair as arguments. (This approach relies on the values having no embedded whitespace, which is the case here.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.