grep-changelogのソースを理解する前に、ChangeLogのフォーマットの理解を兼ねて、Logを小分けするスクリプトを作ってみます。
タイトルの、Logを株分けってのは、私が作った言葉です。複数のChangeLogを一つずつ小分けして、Hashに突っ込むことを、どのようにタイトルにするか悩んだ末、ChangeLogを成長した作物に見立てて株分けとしました。一応英語もdivisionなので意味は合ってます。
いきなり完成版を作るのは、難しいので、少しずつ作ります。
まずは、ChangeLogという名称を含むファイル一覧を作るスクリプト。
opendirで全ファイル一覧を取得して、grepでフィルタリングしてます。
takk@deb9:~/src/binutils-2.28/binutils$ cat t.pl opendir(DIR,"."); @files = grep { /ChangeLog/ } readdir(DIR); closedir(DIR); foreach(@files){ print "$_\n"; } takk@deb9:~/src/binutils-2.28/binutils$
使ってみます。
takk@deb9:~/src/binutils-2.28/binutils$ perl t.pl ChangeLog-2009 ChangeLog-2006 ChangeLog-2014 ChangeLog-2015 ChangeLog-9899 ChangeLog-2012 ChangeLog-2011 ChangeLog-0001 ChangeLog-0203 ChangeLog-2005 ChangeLog ChangeLog-2008 ChangeLog-9197 ChangeLog-2007 ChangeLog-2004 ChangeLog-2013 ChangeLog-2016 ChangeLog-2010 takk@deb9:~/src/binutils-2.28/binutils$
次は、抽出したファイルを一つずつオープンし、行頭に年-月-日の文字列がある行をIDとして、抽出します。
opendir(DIR,"."); @files = grep { /ChangeLog/ } readdir(DIR); closedir(DIR); foreach(@files){ open(INFILE,"<$_"); $id = ""; while(<INFILE>){ chomp(); if(/^\d\d\d\d-\d\d-\d\d/){ $id = "$_"; print "$id\n"; } } close(INFILE); }
これを実行すると、このように各ログが出力されます。
takk@deb9:~/src/binutils-2.28/binutils$ perl t.pl | shuf | head 2010-04-27 Nick Clifton <nickc@redhat.com> 2002-07-10 Jakub Jelinek <jakub@redhat.com> 2012-05-11 Daniel Richard G. <skunk@iskunk.org> 2016-05-18 Maciej W. Rozycki <macro@imgtec.com> 2001-08-03 John Healy <jhealy@redhat.com> 2004-01-02 Nick Clifton <nickc@redhat.com> 2000-04-05 Alan Modra <alan@linuxcare.com.au> 2016-08-12 Nick Clifton <nickc@redhat.com> 2009-03-02 Cary Coutant <ccoutant@google.com> 2012-05-02 Nick Clifton <nickc@redhat.com> takk@deb9:~/src/binutils-2.28/binutils$
次に、抽出したIDをHashのキーとして、各ログ本体をHashに格納します。このとき、元々のフォーマットである行頭にTABがある行をログ本体とみなし、TABを含めて文字列を一行の文字列に連結します。Hashからログを取り出すときは、TABを使用してsplitします。
foreach(@files){ open(INFILE,"<$_"); $id = ""; while(<INFILE>){ chomp(); if(/^\d\d\d\d-\d\d-\d\d/){ $id = "$_"; next; } if(/^ |^$/ && $id ne ""){ $log{$id} .= "$_"; next; } last; } close(INFILE); }
Hashから取り出して表示する処理です。
foreach(keys %log){ $id = $_; @tmp = split /\t/,$log{$_}; print "$id\n"; foreach(@tmp){ print" $_\n"; } print"\n"; }
全文です。
takk@deb9:~/src/binutils-2.28/binutils$ cat -n t.pl 1 %log=(); 2 opendir(DIR,"."); 3 @files = grep { /ChangeLog/ } readdir(DIR); 4 closedir(DIR); 5 6 foreach(@files){ 7 open(INFILE,"<$_"); 8 $id = ""; 9 while(<INFILE>){ 10 chomp(); 11 if(/^\d\d\d\d-\d\d-\d\d/){ 12 $id = "$_"; 13 next; 14 } 15 if(/^ |^$/ && $id ne ""){ 16 $log{$id} .= "$_"; 17 next; 18 } 19 last; 20 } 21 22 close(INFILE); 23 } 24 25 foreach(keys %log){ 26 $id = $_; 27 @tmp = split /\t/,$log{$_}; 28 29 print "$id\n"; 30 foreach(@tmp){ 31 print" $_\n"; 32 } 33 print"\n"; 34 } takk@deb9:~/src/binutils-2.28/binutils$
実行すると、このように抽出されます。
takk@deb9:~/src/binutils-2.28/binutils$ perl t.pl | head -20 2008-10-31 Alan Modra <amodra@bigpond.net.au> * po/id.po: New file. * configure.in (ALL_LINGUAS): Add id. * configure: Regenerate. 2005-10-04 Nick Clifton <nickc@redhat.com> * cxxfilt.c: Treat mangled names specified on the command line in the same way as mangled names read from stdin. Add -i switch to disable the display of implementation details. Add -t switch to disable the demangling of types. * NEWS: Mention the new switches. * doc/binutils.texi (cxxfilt): Document the -i and -t switches. 2004-10-08 Daniel Jacobowitz <dan@debian.org> * readelf.c (get_x86_64_section_type_name): New function. (get_section_type_name): Use it. takk@deb9:~/src/binutils-2.28/binutils$
コメント