3

一連のディレクトリがあります

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

???/af?ディレクトリには非常に長いファイルが含まれていますresults.stdout。このファイルの終わり近くに、文字列があります

 Normal termination: iterations complete!

af3(またはaf4)での計算が成功した場合、それ以外の場合は1つ以上のエラーメッセージがファイルに書き込まれます。各ファイルを手動でチェックする必要をなくすために、要約ファイルを生成するスクリプトを作成しています。

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

これまでのところ、私は以下を調理することができました:

#!/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 

resultしかし、要約ファイルの書き方がわかりません...配列を別のawkプログラムに渡したいのですが、awkは配列変数を受け入れません。助言がありますか?私のプログラミングスタイル、ツールの選択、またはその両方がうまくいかないと思う場合は、アプローチやツールを自由に変更してください:)

4

4 に答える 4

2

printfループ中の結果だけです:

printf 'Massflow        af3      af4\n'
for dir in $(find -maxdepth 1 -type d) # loop on all the directories
do
    printf '     %d  ' "$(printf '%s' "$dir" | sed -e 's/[^0-9]//g')"
    for j in 3 4 # loop on the two subdirs
    do
    result[$j]=$(tac $dir/af$j/tacoma.stdout | awk '
    /TACOMA:- Normal termination: iterations complete!/ {success = 1; exit}
    END { if (success == 1)
              print "Success"
          else
              print "Failure"
        }')
        printf '  %s' "$result[j]"
    done
    printf '\n'
done
于 2012-10-22T13:12:32.997 に答える
2

問題を確認する別の方法は次のとおりです。のgrep代わりにawkを使用し、を使用columnして出力をフォーマットします。

isSuccess() {
    if tac "$1" | grep -q 'Normal termination: iterations complete'; then
        echo Success
    else
        echo Failure
    fi
}

{
    echo Massflow af3 af4
    for dir in ???; do
        echo "$dir" $(isSuccess "$dir/af3/results.stdout") $(isSuccess "$dir/af4/results.stdout")
    done
} | column -t
于 2012-10-22T21:32:47.410 に答える
2

まず、ファイル全体を元に戻すことにはメリットがないため、tacを使用しないでください。ファイルをawkに渡すだけです。

2番目のforループを省略して、2つの結果を保存し、後で印刷することができます。

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

@EdMortonから:bashなしでのみ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
于 2012-10-22T13:22:31.070 に答える
1

最初にfindやloopなどを使用して出力ファイルのリストを作成してから、リスト全体をawkに渡します。

for dirName in ???
do
   for subName in af3 af4
   do
      files="$files $dirName/$subName/results.stdout"
   done
done

awk '
FNR == 1 {
   split(FILENAME,dfA,"/")
   dirName = dfA[1]
   subName = dfA[2]
   dirNames[dirName]
   subNames[subName]
}

/Normal termination: iterations complete!/ {
   succ[dirName,subName]
}

END {
   printf "Massflow"
   for (subName in subNames) {
      printf "\t%s",subName
   }
   print ""

   for (dirName in dirNames) {
      printf "%s", dirName
      for (subName in subNames) {
         printf "\t%s", ( (dirName,subName) in succ ? "Success" : "Failure" )
      }
      print ""
   }
}
' $files

最後に$filesを引用しなかったので、例として正しく展開されることに注意してください。最初に考えたように、ディレクトリ構造がdir/fileではなくdir/subdir / results.stdoutであることがわかったので、答えを編集しました。

@DeltaIVのresuestごとのコメント付きバージョン

for dirName in ???
do
   for subName in af3 af4
   do
      files="$files $dirName/$subName/results.stdout"
   done
done

awk '
# FNR == 1 is true at the first line of each input file
FNR == 1 {

   split(FILENAME,dfA,"/")
   dirName = dfA[1]
   subName = dfA[2]

   # Use array dirNames as the set of all top level directory names
   # and array subNames as the set of all sub-directory names so later
   # we can loop through them all to produce output.
   dirNames[dirName]
   subNames[subName]
}

# Check if the current line of the current input file contains the
# success indication text.
/Normal termination: iterations complete!/ {

   # The success indication text was found in the current file so
   # updated array succ which is the set of all dirName/SubName
   # pairs that had the success indication in their results file.
   succ[dirName,subName]
}

# "END" is true after all input files have been processed.
END {

   # Print the header line consisting of Massflow followed by the
   # sub-directory names
   printf "Massflow"
   for (subName in subNames) {
      printf "\t%s",subName
   }
   print ""

   # Loop through the set of dirNames so you get one per row
   # and for each dirName process all sub-directory names
   for (dirName in dirNames) {
      printf "%s", dirName
      # Loop through the set of subNames and process each one
      # as a new tab-separated column of output
      for (subName in subNames) {
         # If the current dirName/subName combination is in the succ
         # set then print "Success", otherwise print "Failure".
         printf "\t%s", ( (dirName,subName) in succ ? "Success" : "Failure" )
      }
      # Move down to the next row of output.
      print ""
   }
}
' $files
于 2012-10-22T16:51:33.713 に答える