Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shell script: with awk, write string1 if string0 is found, else string2

Tags:

bash

shell

awk

I've got a sequence of directories

079/af3
100/af4
120/af3
  . 
  .
  .

Each ???/af? directory contains a very long file results.stdout. Close to the end of this file, one finds the string

 Normal termination: iterations complete!

if the computation in af3 (resp. af4) was successful, otherwise one or more error messages are written in the file. To avoid having to check each file by hand, I'm writing a script which generates a summary file:

 Massflow        af3      af4 
      079    Success  Failure
      100    Failure  Success
      120    Success  Success
        .      .       .
        .      .       .

So far, I've been able to cook up the following:

#!/bin/bash

strlen="9" # want to keep the format flexible, instead than hardcode it
format0="%"$strlen"s %"$strlen"s %"$strlen"s\n"
# write the header of file summary
awk -v format="$format0" ' BEGIN { printf format, "Massflow", "af3", "af4"
                             } ' >> summary


for dir in ??? # loop on all the directories
do
    for j in 3 4 # loop on the two subdirs
    do
    result[$j]=$(tac $dir/af$j/results.stdout | awk '
    /TACOMA:- Normal termination: iterations complete!/ {success = 1; exit}
    END { if (success == 1)
              print "Success"
          else
              print "Failure"
        }')
    done
done
exit 

However, I don't know how to write the summary file...I'd like to pass the result array to another awk program, but awk doesn't accept array variables. Any suggestions? Feel free to change the approach or even the tools, if you think my programming style, tools choice or both suck :)

like image 781
DeltaIV Avatar asked Dec 10 '25 14:12

DeltaIV


1 Answers

First, don't use tac, because there's no benefit in reversing the whole file. Just give the files to awk.

You can omit the second for loop and save the two results and print them afterwards:

for dir in ??? # loop on all the directories
do
    for j in 3 4; do
        af[$j]=$(awk '/TACOMA:- Normal termination: iterations complete!/ {success = 1; exit}
                   END { if (success == 1)
                             print "Success"
                         else
                             print "Failure"
                   }'  $dir/af$j/results.stdout)
     done

     awk -v format="$format0" "BEGIN { printf format, \"$dir\", \"${af[3]}\", \"${af[4]}\"; } " >> summary
done

From @EdMorton in bash only without awk:

for dir in ??? # loop on all the directories
do
    for j in 3 4; do
        if grep -q "TACOMA:- Normal termination: iterations complete!" "$dir/af$j/results.stdout"; then
            af[$j]="Success"
        else
            af[$j]="Failure"
        fi
     done

     printf "$format0" "$dir" "${af[3]}" "${af[4]}" >> summary
done
like image 86
Olaf Dietsche Avatar answered Dec 13 '25 04:12

Olaf Dietsche



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!