列の内容に基づいてファイルを別々のファイルに分割する+各新しいファイルにヘッダーと合計レコード数を追加する[閉じる]

列の内容に基づいてファイルを別々のファイルに分割する+各新しいファイルにヘッダーと合計レコード数を追加する[閉じる]
  • ヘッダーはHで始まります。
  • トレーラーはTで始まります。
  • R で始まるレコード
  • 「|」で区切られた

入力ファイルのサンプル

  • トレーラーレコードの3番目の列はレコード数、4番目の列は金額列の合計です。
  • 分割後のトレーラーは、数と合計の列を含む次の形式で新しいファイルに追加する必要があります。
  • INPUT レコードは日付順に従わない。たとえば、最初のレコードは2019-03-05として記録され、最後のレコードも同じ日付です。

入力ファイル:

H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-06|10.00
R|abc|2019-03-05|30.00
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
R|abc|2019-03-05|30.00
T|20200425|8|225.00

期待される出力

ファイル1:次の名前で保存する必要があります。20190305.txt

H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
R|abc|2019-03-05|30.00
T|20200425|4|90.00

ファイル2:次の名前で保存する必要があります。20190306.txt

H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
R|abc|2019-03-06|10.00
T|20200425|4|135.00

答え1

別のawkソリューション

awk -F'[|]' '
     $1=="H"{h=$0"sum"; next}
     $1=="R"{o=$3".txt";gsub("-","",o);
           if (! sum[o]) print h > o; 
           printf ("%s|%s|%s|%.2f\n", $1, $2, $3, $4) > o; sum[o]+=$4; c[o]++}
     $1=="T"{for (o in sum) printf ("%s|%s|%d|%.2f\n", $1, $2, c[o], sum[o]) > o}' file;
tail -n +1 2019*.txt

出力

==> 20190305.txt <==
H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
T|20200425|3|60.00

==> 20190306.txt <==
H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
T|20200425|3|125.00

FSに設定|

awk -F'[|]' '

ヘッダー行の場合は、キャプチャして欠落しているテキストを追加してから、次の行に移動します。

     $1=="H"{h=$0"sum"; next}

レコードの場合は、キャッチして$3".txt"削除して-出力ファイル名を取得します。

     $1=="R"{o=$3".txt";gsub("-","",o);

この出力ファイルの合計配列がまだ初期化されていない場合、printファイルヘッダーは

           if (! sum[o]) print h > o; 

出力形式を指定し、最後のフィールドを変更してprintf関連ファイルに保存します。

           printf ("%s|%s|%s|%.2f\n", $1, $2, $3, $4) > o;

ファイル名をインデックスとして使用して、この出力ファイルのsumレコード数を更新します。c

           sum[o]+=$4; c[o]++}

tail-endの場合は、sum配列を繰り返してprintfファイル名を回復し、各出力ファイルに関連する要約行を作成します。o

     $1=="T"{for (o in sum) printf ("%s|%s|%d|%.2f\n", $1, $2, c[o], sum[o]) > o}' file;

出力表示

tail -n +1 2019*.txt

答え2

あなたはこれを行うことができますawk

if($0 ~ /^$/){next};→空白行を無視

if(NR==1){hd=$0;h=1;next}→店舗名「HD」変数を指定し、解析のために次の行に移動します。

f=$3$4$5→ ファイル名を次に保存します。「F」変数("-"も区切り文字であるため、対応する値は区切りで使用可能)n ${3,4,5}それぞれ。最後に、印刷プロセス中に「.txt」を追加します。

awk -F'[|-]' '{
    if($0 ~ /^$/){next};
    if(NR==1){hd=$0;h=1;dt=$2;next}
    f=$3$4$5;sum+=$6;c++;
    if ( dval != f ) { h=1;printf "%s|%s|%s|%.2f\n","T",dt,c,v6 >> dval".txt";temp=$6;sum=0;c=0};
    if ($0 ~ /^T/ ) { next; }
    if ($0 ~ /^R/ ){v6=sum+temp;}
    if(h){print hd"\n\n"$0"\n" > f".txt"; h=0;}else{ print $0"\n" >> f".txt";}dval=f;
    }' inputFile

出力:

$ cat 20190305.txt 
H|20200425|abcd|sum
R|abc|2019-03-05|10.00    
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
T|20200425|3|60.00

$ cat 20190306.txt 
H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
T|20200425|3|125.00

答え3

次のことを試すことができます。

awk -F'|' '
  # get the 2nd field of the header
  NR == 1 { 
    a = $2 
    h = $0
    next
  } 
  # get the date formatted
  NR == 2 { 
    d = $3; gsub(/-/,"",d) 
    print h > d
  } 
  # if the line starts with 'R', sum the column and get the count of them
  $1 == "R" { 
    sum += $4
    ++c 
  } 
  {
    print > d
  }
  # print the final line with variables acquired
  END { 
    OFS = "|"; print "T",a,c,sum".00" > d
  }
' file

出力:

$ cat 20190305.txt 
H|20200425|abcd|sum
R|abc|2019-03-05|10.00    
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
T|20200425|3|60.00

$ cat 20190306.txt 
H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
T|20200425|3|125.00

関連情報