上と下の手順3の値より少なくとも2倍大きい値を同じ列に印刷します。

上と下の手順3の値より少なくとも2倍大きい値を同じ列に印刷します。

リストがあります。

2
2
2
3
2
2
2
4
2
2
2

上と下の3段階の値より少なくとも2倍大きい値を同じ列に印刷したいと思います。

出力は

4

どうすればいいですか?私も同様の質問をしました。ここ、よりよく説明するためにここに書いています。ありがとうございます。

20171006更新:実際の入力ファイルを過度に単純化して申し訳ありません。実際にはリストではなくテーブルです。複数の列(列2、3、4など)から選択し、列1を印刷する必要があります。その列に対してこのようなスクリプトの情報をどのようにマージしますか?

A 2 2 2
B 2 2 2
C 2 2 2
D 3 3 3
E 2 2 2
F 2 2 2
G 2 2 2
H 4 4 4
I 2 2 2 
J 2 2 2 
K 2 2 2 

そして得る

H

答え1

でこれを行うことができますawk。 3行目と最後の行を6行目と現在の行とを比較するには、最初の6行を保存する必要があります。これの一般的なトリックは、保持したい行数にインデックス付きの配列であるNR%6リングバッファを使用することです6

awk '
  NR > 6 {
    x = saved[NR%6]; y = saved[(NR - 3) % 6]; z = $0
    if (y >= 2*x && y >= 2*z) print y
  }
  {saved[NR % 6] = $0}'  < file

編集するには:比較するキーと値を保存します。

awk -v key=1 -v value=2 '
  NR > 6 {
    x = saved_value[NR%6]; y = saved_value[(NR - 3) % 6]; z = $value
    if (y >= 2*x && y >= 2*z) print saved_key[(NR - 3) % 6]
  }
  {saved_key[NR % 6] = $key; saved_value[NR % 6] = $value}'  < file

どこkeyに印刷する列のインデックスとvalue比較する値を含む列があります。

または、2、3、4列(平均など)に基づいて目的の指標を選択します。

awk '
  {metric = ($2 + $3 + $4) / 3}
  NR > 6 {
    x = saved_metric[NR%6]; y = saved_metric[(NR - 3) % 6]; z = $metric
    if (y >= 2*x && y >= 2*z) print saved_key[(NR - 3) % 6]
  }
  {saved_key[NR % 6] = $key; saved_metric[NR % 6] = $metric}'  < file

答え2

メモリ内のファイル全体を読み取らずに:

paste <(tail -n+4 file.txt | head -n-3) <(head -n-6 file.txt) <(tail -n+7 file.txt) |
    awk '$1 >= 2*$2 && $1 >= 2*$3 {print $1}'

<(...)これには、構成(AT&Tkshまたはbash)を処理できるシェルと負のzshオフセットheadをサポートする実装が必要です。

説明する:上記のコマンドは、paste現在の値、ステップ3の上の値、およびステップ3の下の値を同じ行に入れて、2倍awk以上の条件を確認します。

答え3

アッ解決策:

awk 'function mean(sum){ 
          m=sum/3; return (int(m) == m)? m: int(m)+1 
     }
     { a[NR]=$0 }
     END{ 
         for(i=4;i<=NR-3;i++) 
             if (a[i]>=mean(a[i-3]+a[i-2]+a[i-1])*2 &&
                a[i]>=mean(a[i+3]+a[i+2]+a[i+1])*2) 
             print a[i] 
     }' file

  • a[NR]=$0- すべての値をaレコード番号で索引付けされた配列として収集NR

出力:

4

答え4

したがって、これを行うには、3 + 1 + 3入力行のスライドウィンドウを維持する必要があります。

awk -vn=3 -va=2 'BEGIN { N=2*n+1 } { t=(NR-n)%N; m=NR%N; b=(NR+n)%N; w[b]=$0 } NR >= N && w[m] >= a*w[t] && w[m] >= a*w[b] { print w[m] }' file

nこれにより、条件を満たすすべての値が印刷され、コマンドラインで変数を調整(変更)して距離を簡単に変更でき、重みを変更-vn=3(変更)して距離を簡単に変更できるという利点があります。a-va=2

このコードは最後のN値を循環バッファに格納します。ここで、Nは2 * n + 1ですw。中間値がバッファの最初の値(「top」の場合)の倍数と、バッファの最後の値(「bottom」の場合)の倍数より大きい場合、w[m]それを印刷します。aw[t]taw[b]b


公開スクリプトawk

BEGIN   { N = 2*n + 1 }

        {
            t = (NR - n)%N
            m = NR%N
            b = (NR + n)%N
            w[b] = $0
        }

NR >= N && w[m] >= a*w[t] && w[m] >= a*w[b] { print w[m] }

関連情報