Sufyan
Sufyan

Reputation: 123

AWK inside a loop for making multiple files form single files

I have the below file named ABCD.vasp:

# A B C D
1.000000
     13.85640621        0.00000000        0.00000000
      4.61880236       13.06394496        0.00000000
      0.00000000        0.00000000       45.25483322
A B C D
   32      32      32      32
Selective dynamics
Direct
      0.00000000        0.00000000        0.00000000 F F F
      0.00000000        0.00000000        0.12500000 F F T
      0.00000000        0.00000000        0.25000000 F F T
      0.00000000        0.00000000        0.37500000 F F T
      0.50000000        0.00000000        0.00000000 F F F
      0.50000000        0.00000000        0.12500000 F F T
      0.50000000        0.00000000        0.25000000 F F T
      0.50000000        0.00000000        0.37500000 F F T
      0.12500000        0.37500000        0.06250000 F F T
      0.12500000        0.37500000        0.18750000 F F T
      0.12500000        0.37500000        0.31250000 F F T  

The operations which I want to do on the above file:

  1. I want to copy the first 9 lines into a new file named test.vasp
  2. Line number 10 onwards, if the third column is >=0.25 then the first column should be increased by 0.025 and the entire line should be appended to test1.vasp
  3. Line number 10 onwards, if the third column is <0.25 then the entire line should be appended to test1.vasp
  4. Step-2 and Step-3 I want to repeat from 0.025 to 0.25 for test1.vasp to test10.vasp

I tried the below command which is not working:

for ((i=1;i<=10;i++));do
        outputfile=test"$i".vasp
        awk -v I=$i 'NR > 9 && $3+0 >= 0.25 {
        p = $1; p =($I * 0.025); sub(/[^ \t]+/, sprintf("%.8f", p)) } 1' $inputfile > $outputfile
done

Please suggest a solution to this in awk or sed

Upvotes: 1

Views: 217

Answers (4)

Sufyan
Sufyan

Reputation: 123

From answer to my earlier question: https://stackoverflow.com/a/62556657/12832411

This worked for me:

for ((i=1;i<=10;i++));do
   outputfile=test"$i".vasp
   awk -v I=$(( i * 0.025 )) 'NR > 9 && $3+0 >= 0.25 {
   p = $1; p +=I; sub(/[^ \t]+/, sprintf("%.8f", p)) } 1' $inputfile > $outputfile
done

Upvotes: -1

anubhava
anubhava

Reputation: 785581

You may use this awk script.

cat incr.awk

NR <= 9 {
   s = s $0 ORS
   next
}
{
   r[++n] = $0
}
END {
   for (i=1; i<=10; i++) {
      fn = "test" i ".vasp"
      printf "%s", s > fn
      for (k=1; k<=n; ++k) {
         split(r[k], a)
         if (a[3] >= 0.25) {
            sub(/[^\t]+/, sprintf("%.8f", a[1] + .025), r[k])
         }
         print r[k] > fn
      }
      close(fn)
   }
}

Then run it as:

awk -f incr.awk file

Upvotes: 1

karakfa
karakfa

Reputation: 67507

for the numerical section you can do something like this

$ awk 'NR>9{for(i=1;i<=10;i++)
              {f="test" i ".vasp";
               if($3>=0.25) $1=sprintf("%.8f",$1+0.25)
               print > f}}' file

will give

$ head *.vasp | column -t

==>         test1.vasp   <==
0.00000000  0.00000000   0.00000000  F  F  F
0.00000000  0.00000000   0.12500000  F  F  T
0.25000000  0.00000000   0.25000000  F  F  T
0.25000000  0.00000000   0.37500000  F  F  T
0.50000000  0.00000000   0.00000000  F  F  F
0.50000000  0.00000000   0.12500000  F  F  T
0.75000000  0.00000000   0.25000000  F  F  T
0.75000000  0.00000000   0.37500000  F  F  T
0.12500000  0.37500000   0.06250000  F  F  T
0.12500000  0.37500000   0.18750000  F  F  T
==>         test10.vasp  <==
0.00000000  0.00000000   0.00000000  F  F  F
0.00000000  0.00000000   0.12500000  F  F  T
2.50000000  0.00000000   0.25000000  F  F  T
2.50000000  0.00000000   0.37500000  F  F  T
0.50000000  0.00000000   0.00000000  F  F  F
0.50000000  0.00000000   0.12500000  F  F  T
3.00000000  0.00000000   0.25000000  F  F  T
3.00000000  0.00000000   0.37500000  F  F  T
0.12500000  0.37500000   0.06250000  F  F  T
0.12500000  0.37500000   0.18750000  F  F  T
==>         test2.vasp   <==
0.00000000  0.00000000   0.00000000  F  F  F
0.00000000  0.00000000   0.12500000  F  F  T
0.50000000  0.00000000   0.25000000  F  F  T
0.50000000  0.00000000   0.37500000  F  F  T
0.50000000  0.00000000   0.00000000  F  F  F
0.50000000  0.00000000   0.12500000  F  F  T
1.00000000  0.00000000   0.25000000  F  F  T
1.00000000  0.00000000   0.37500000  F  F  T
0.12500000  0.37500000   0.06250000  F  F  T
0.12500000  0.37500000   0.18750000  F  F  T
==>         test3.vasp   <==
0.00000000  0.00000000   0.00000000  F  F  F
0.00000000  0.00000000   0.12500000  F  F  T
0.75000000  0.00000000   0.25000000  F  F  T
0.75000000  0.00000000   0.37500000  F  F  T
0.50000000  0.00000000   0.00000000  F  F  F
0.50000000  0.00000000   0.12500000  F  F  T
1.25000000  0.00000000   0.25000000  F  F  T
1.25000000  0.00000000   0.37500000  F  F  T
0.12500000  0.37500000   0.06250000  F  F  T
0.12500000  0.37500000   0.18750000  F  F  T

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 204015

Don't call awk multiple times just write to multiple output files for each line inside awk, like this:

{
    c=0
    for (i=0.025; i<=0.25; i+=0.025) {
        print ...whatever... >> ("test" (++c) ".vasp")
    }
}

Upvotes: 1

Related Questions