【Lifehacks】TSV形式データを印刷形式に整形する

■タスク
 TSV形式データを印刷形式に整形する。


■背景
・特定ハッシュタグに関連付いた呟きを印刷してまとめて読みたい。
別途加工したTSV形式データを、印刷しやすいのように整形したい。


■方法
 Perlスクリプトにより印刷形式に整形します。


■仕様
・入・出力ファイルの文字コードWindows-31J (CP932)とします。

・入力ファイルはTSV形式とします。
 具体的には以下の形式です。
 - 1件1行。
 - 1件形式:USERIDSTATUSIDLENGTHTITLETWEET
  - USERID:TwitterユーザID。
  - STATUSID:呟きのID。
  - LENGTH:呟き文字数。
  - TITLE:呟き仮タイトル。呟きの先頭20文字。
  - TWEET:呟き本体。

・出力ファイルは以下の形式に整形します。
 - 1000件毎に章見出しを挿入します。
  - 空行
  - 章見出し行
  - 空行
 - 章見出し行形式:    ■ START_CNT - END_CNT ■
  - START_CNT:開始呟き一連番号。8桁、ゼロ詰め。
  - END_CNT:終了呟き一連番号。8桁、ゼロ詰め。
 - 1件3論理行。
  - 見出し行
  - 呟き本体
  - 空行。
 - 見出し行形式:CNT USERID STATUSID
  - CNT:呟き一連番号。
  - USERID:TwitterユーザID。
  - STATUSID:呟きのID。


■使用方法
> perl SgTwTsvToPrint.pl < Input.txt > Output.txt


■プログラム

# 
# SgTwTsvToPrint.pl
# TSVから印刷用テキストに変換する。
# 
# Author: Orihika Ikuo 
# Create: 2009.09.30 twnovelオフ会対応急造版。 
# Update: 2009.10.08 修正版。
# 

##### Pragma
use strict;
use warnings;
use utf8;

##### Module
use Encode;

##### Setting
our $sec_cnt                 = 1000;
our $fmt_cnt                 = '%08d';
our $fmt_usr                 = '%-18s';
our $pad_len_cnt             = 8;
our $pad_len_usr             = 20;

##### Constant
our $ENC_SJIS                = ':encoding(:shiftjis)';
our $ENC_CP932               = ':encoding(:cp932)';
our $ENC_UTF8                = ':encoding(:utf8)';
our $ERR_ILL_FORMAT          = "ERR: Illegal format.";

##### Global
binmode STDIN,  $ENC_CP932;
binmode STDOUT, $ENC_CP932;

##### Main routine
&SgTwTsvToPrint();

sub SgTwTsvToPrint {
  my $dat_line;
  my $cnt                    = 0;
  my $usr;
  my $status;
  my $len;
  my $title;
  my $tweet;
  my $usr_padded;

  while ($dat_line = <STDIN>) {
    if ($cnt % $sec_cnt == 0) {
      SgCmPrNextSecTitle($cnt);
    }
    $cnt++;

    chomp($dat_line);

    ($usr, $status, $len, $title, $tweet) = split(/\t/, $dat_line);

    printf STDOUT "$fmt_cnt  $fmt_usr  %s\n", $cnt, $usr, $status;
    print  STDOUT "$tweet\n";
    print  STDOUT "\n";
  }

  &SgCmPrTheEndOfDocument;
}

sub SgCmPrNextSecTitle {
  my $cnt = shift;

  print  STDOUT "\n";
  printf STDOUT "    ■ $fmt_cnt - $fmt_cnt\n", $cnt + 1, $cnt + $sec_cnt;
  print  STDOUT "\n";
}

sub SgCmPrTheEndOfDocument {
  print STDOUT "\n";
  print STDOUT "To be continued.\n";
}


■備考
twnovelオフ会で回覧した「All of twnovel 0001」は、このデータから製作しています。