編集する:

編集する:

4番目の列の最初の行の値が(同じ命名スタイルを持つ他の8つのファイルと比較して)最も高い場合、ファイル(実際にはテーブル)を移動できる次のプログラムがあります。スクリプトは次のとおりです。

#! /bin/bash
river=mississippi
highest=1
for model in H08 MPI-HM WBM PCR-GLOBWB
do
  for gcm in GFDL-ESM2M HadGEM2-ES IPSL-CM5A-LR MIROC-ESM-CHEM NorESM1-M
  do
    for scenario in hist rcp8p5 rcp4p5
    do
      RESULT=$(awk 'FNR==1 {print $4, FILENAME}' ${model}_${gcm}_${scenario}_${river}[1-9]/${model}_${gcm}_${scenario}_${river}[1-9].txt | sort -n -r| head -1) 
      highest="$(echo $RESULT | cut -d ' ' -f1 )"
      hifile="$(echo $RESULT | cut -d ' ' -f2 )"
      echo "highest was $highest in $hifile"
      cp "$hifile" "/home/stevens/SUMARIO/Fred/highest_discharge/${river}/${model}_${gcm}_${scenario}_${river}.txt"
    done
  done
done

次に、最も高い値(最初の行、4番目の列)を持つファイルをコピーするのではなく、4番目の列、同じ列に最も高い平均を持つファイルをコピーするようにこのスクリプトを調整したいと思います。他のファイルと比較してください。どんなヒントや提案でも大変感謝します!

答え1

結果の計算方法を変更するだけです。

RESULT=$(awk '{x+=$4} END{print x/NR, FILENAME}' ${model}_${gcm}_${scenario}_${river}[1-9]/${model}_${gcm}_${scenario}_${river}[1-9].txt | sort -n -r| head -1) 

上記は、4行目のすべての値を加算し、最後の行数で割った結果を印刷することです。

行数で除算するため、ファイルに空白行があると、予期しない結果が発生します。合計はこれを考慮せずに行数で割ります。

編集する:

最初の試みで、スクリプトが最後のファイルの最大値のみを考慮するようにするエラーが発生しました。みんなファイルが処理されました)

正しいバージョン:

awk 'FNR==1 && NR>1 {print x/nr, file;x=0}{x+=$4; nr=FNR; file=FILENAME} END{print x/nr, file, x, nr}' ${model}_${gcm}_${scenario}_${river}[1-9]/${model}_${gcm}_${scenario}_${river}[1-9].txt | sort -n -r| head -1

説明する:

  • 印刷するたびにより早いファイルが解析されました。新しいファイルを読み込むたびにFNRがリセットされるので、新しいファイルが開始されたことを確認し(FNR == 1)、最初のファイルにないことを確認します(NR> 1)。その場合は、前のファイルから保存された平均とファイル名を印刷します。 xもリセットします(平均を維持します)。
  • それ以外の場合はxの計算を開始します。また、ファイル(FNR)のレコード数とファイル名を保存します。
  • 最後に、最後のファイルの平均を印刷します。

答え2

列自体の位置を指定する方法を見つけたようです。今やるべきことは、すべての4つのファイルの4番目の列の平均を取得し、平均が最も高いファイルをコピーすることです(すでに言及した内容をもう一度参照してください)。

基本的にすべきことは、4つのファイルのそれぞれの4列の出力を加算し、4列の行数で割って平均を求めることです。次に、平均が最も高いファイルをコピーします。

平均を求める方法だけ知りたいと思いますが、そうですか?

echo "$file1_col4" | wc -lwc -l <<< "$file1_col4"すでに持っている必要があるorなどの操作を実行して、行数を簡単に取得できます。後で分割できるように、各値を変数に保存します。それでは、次のように言いましょう。

file1_col4_rows=$(echo "$file1_col4" | wc -l) 

この列の合計を取得するには、次の手順を実行する必要があります。

file1_col4_total=$(echo "$file1_col4" | awk '{total = total + $1}END{print total}')

4つのファイルすべてに対してこれを行い、以前に変数に設定した列の合計行数に分割できます。 Bashにはこれを処理する組み込み機能がありますが、私は以下を使用することを好みますperl

file1_avg=$(perl -e "print $file1_col4_total/$file1_col4_rows")

4つのファイルすべてに対してこれを行うと、変数を参照して平均4番目の列が最も高いファイルを簡単に確認し、$fileN_avg最も高い値を持つ変数を持つファイルをコピーできます。

file_to_copy="$(echo "file1 $file1_avg
file2 $file2_avg
file3 $file3_avg
file4 $file4_avg" |
sort -nrk2 |
head -1 |
awk '{print $1}')"

それから単にcp "$file_to_copy" /path/where/it/belongs/

関連情報