そうでない場合 Awk NR: エントリのないテーブルのセクションヘッダーを削除する方法

そうでない場合 Awk NR: エントリのないテーブルのセクションヘッダーを削除する方法

毎日変わるデータを表にまとめようとしています。 30個を超える項目を含む行のみを表示するようにテーブルをまとめました。

ただし、元のテーブルのエントリ数が30を超えない場合があります。これが発生した場合、要約にスペース全体を必要としません。では、このセクションのヘッダー全体をどのように削除できますか?

理想的には、5つのセクションすべてに項目がない場合は、行を印刷しないでください(または私が試したように、「なし:30より大きい項目はありません」という文字列のみを印刷する必要があります)。

5つの部分で構成されたサマリーテーブルの例、summary_output.txt:

=========================================================================================================
Month: Jun      

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun     

Counter Name                                06/05 14:00     06/05 13:00     06/05 12:00     06/05 11:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun      

Counter Name                                06/05 10:00     06/05 09:00     06/05 08:00     06/05 07:00
=========================================================================================================


=========================================================================================================
Month: Jun    

Counter Name                                06/05 06:00     06/05 05:00     06/05 04:00     06/05 03:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================
Month: Jun      

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================

ご覧のとおり、3 番目のセクションは、Original_output.txt ファイルに 30 より大きい項目がないため空です。ただし、ヘッダーはまだ存在します。

私の要約コード(アクション):

awk '$1=="Month:"||$1==""||$1=="Counter"||(index($1, "=")!=0)||$3>=30|| $4>=30 || $5>=30||$6>=30' original_output.txt>>summarised_output.txt

ヘッダーを削除してみました(動作しません)。

touch summarised_output_temp.txt
awk '{if ($1=="Month:"||$1==""||$1=="Counter"||(index($1, "=")!=0)||$3>=30|| $4>=30 || $5>=30||$6>=30) print $0}' original_output.txt >> summarised_output_temp.txt
if (((wc -l < summarised_output_temp.txt)==42))
then
echo "None: there is no entry larger than 30" >> summarised_output.txt
else
cat output_7_temp.txt>>summarised_output.txt
fi

試行中にエラーが発生しました:

line 3: ((: (wc -l output_7_temp.txt | awk {print $1})==42: syntax error: invalid arithmetic operator (error token is ".txt | awk {print $1})==42")

答え1

GNUがある場合は、awk次のスクリプトを使用できます。

awk -v RS='={105}[^=]*={105}' 'NF{print oRT,$0} {oRT=RT}' file

ヘッダーは複数行のレコード区切り文字に設定されますRS。 105文字2文字とその間の文字で構成されています=

この変数は、RT各レコードのレコード区切り文字をキャプチャして変数に保存し、oRT印刷する要素がある場合は次のレコードに印刷します(キャプチャにはcatchを使用NF)。

答え2

以下を含む実行可能スクリプト test.awk を生成します。

awk '
  # { print "read " $0 }
  /^SYS/ {
    if (H) {
      if (F) {print F} else { F="\r\n\r\n"}
      print H; H=""}
    print
    next
  }
  /^./ {
    H=$0
    for (i=1; i<5; i++) {
      getline
      H = H "\r\n" $0
    }
    next
  }
' $@

そして走る

test.awk original_output.txt

"/^SYS/{" は、データ行を識別する任意のものに置き換えることができます。

答え3

この問題はPerlを使用して次のように解決できます。

パスワード

perl -F'/^=+$/m' -lan -0777e '
   my($dashes) = /^(=+)$/m;
   shift @F; pop @F;
   while ( @F > 1 ) {
      my($h, $s) = splice @F, 0, 2;
      next if $s =~ /^(?:\h*\n)+$/;
      print join $dashes, q(), $h, $s, !@F ? q() : ();
   }
' input.txt

出力

=========================================================================================================
Month: Jun

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/05 14:00     06/05 13:00     06/05 12:00     06/05 11:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/05 06:00     06/05 05:00     06/05 04:00     06/05 03:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45



=========================================================================================================
Month: Jun

Counter Name                                06/04 18:00     06/04 17:00     06/04 16:00     06/04 15:00
=========================================================================================================
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45
SYS.SYS.SYS.SYS.SYS.SYS.                  : 45              45              45              45


=========================================================================================================

説明する

  • ため息をつく: -0777選ぶ真珠可能にする
  • ダッシュに沿ってファイル全体を分割します(1つの長い文字列として扱われます)。/^=+$/メートル指定された行に繰り返される等価のみが含まれる場所がファイルを分割する場所であることを意味します。
  • -ㅏオプションが作る真珠分割された部分を配列で埋めます。@F
  • -NPerlのオプションは、次のレコードを読む前に自動印刷を無効にします。アッ- 入力から読み取ったレコードのループに似ています。
  • まず、入力に点線を保存します。
  • 分割操作によって最初の要素と最後の要素が空になるため、次から始めます。@F主な作業を行う前に配列を実行してください。
  • 2つの要素を使用するwhileループを設定します(接合)いつかから@Farray. 最初はタイトル、2番目はセクションです。配列に要素が2つ以上残っている限り、ループは続きます。
  • キーは、処理タイトル/セクションデュエットをスキップするかどうかを決定することです。これは、セクションに空白行のみが含まれているか横に空白がある行です(\時間)。正規表現は次のとおりです。/^(?:\h*\n)+$/
  • セクションが空でない場合は、タイトル/セクションのデュオをダッシュ​​と関連付ける必要があります。最後のタイトル/セクションが合わされたら、ダッシュを追加して仕上げる必要があることを忘れないでください。

答え4

Oliveの答えと似ていますが、もう少し簡単かもしれません。

gawk -v RS='=+\n' '
    NR % 2 == 0 {header = $0; next}
    /[^[:space:]]/ {printf "%s", RT header RT $0}
    END {print RT}
' output.txt 

■ 行を=レコード区切り文字として使用します。ヘッダーはすべての偶数レコード用です。 「content」に空白以外の文字が含まれている場合、「content」は空ではありません。

RT「レコード区切り文字であるRSが表すテキストと一致する入力テキストです。これは、レコードが読み取られるたびに設定されます。」を含むGNU awk固有の変数です。

関連情報