c6fb2aaa3184abdb4025dcac73a2f6ec41c42b9a
Perl/Amazon/BrowseNodeSearch.md
... | ... | @@ -0,0 +1,157 @@ |
1 | +# XML::Simple を使って XML を読む |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- Amazon Web Services の BrowseNodeSearch の結果をXML::Simpleを使って解析し、子ノードを探索する。 |
|
6 | +- 親ノード/子ノードの表示だけ行いファイル保存はしないようにした。(2009/12/05) |
|
7 | +- AssociateTagを指定するようにした。(2011/10/27) |
|
8 | +- [Web版](http://www.takeash.net/cgi-bin/Amazon/BrowseNodes.cgi) |
|
9 | + |
|
10 | +## BrowseNodeSearch |
|
11 | +- 下記URLにリクエストすることで、あるBrowseNodeの子ノード一覧を取得できる。 |
|
12 | + - XXXXは調べたいBrowseNode。 |
|
13 | +``` |
|
14 | +http://webservices.amazon.co.jp/onca/xml |
|
15 | + ?Service=AWSECommerceService |
|
16 | + &Operation=BrowseNodeLookup |
|
17 | + &ResponseGroup=BrowseNodeInfo |
|
18 | + &AssociateTag=xxxx-22 |
|
19 | + &BrowseNodeId=XXXX |
|
20 | +``` |
|
21 | + |
|
22 | +## スクリプト |
|
23 | +- [BrowseNodes2.zip](BrowseNodes2.zip) |
|
24 | +```perl |
|
25 | +#!/usr/local/bin/perl |
|
26 | +# |
|
27 | +# BrowseNodes2.pl |
|
28 | +# Amazon Web Services BrowseNodes 探索スクリプト |
|
29 | +# by TakeAsh |
|
30 | +# |
|
31 | +# http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/BrowseNodeIDs.html |
|
32 | +# |
|
33 | +# 2009.12.05 v2.00 親ノード/子ノードの表示だけ行いファイル保存はしないようにした。 |
|
34 | +# 2011.10.27 v2.01 AssociateTagを指定するようにした。 |
|
35 | + |
|
36 | +use strict; |
|
37 | +use warnings; |
|
38 | +use utf8; |
|
39 | +use Encode; |
|
40 | +use URI::Amazon::APA; |
|
41 | +use LWP::UserAgent; |
|
42 | +use XML::Simple; |
|
43 | +use YAML::Syck; |
|
44 | + |
|
45 | +$YAML::Syck::ImplicitUnicode = 1; |
|
46 | + |
|
47 | +my $charsetConsole = 'CP932'; |
|
48 | +#my $charsetInFile = 'UTF-8'; |
|
49 | +#my $charsetOutFile = 'UTF-8'; |
|
50 | + |
|
51 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
52 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
53 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
54 | + |
|
55 | +my $confyaml = './ID.yaml'; |
|
56 | +my $conf = YAML::Syck::LoadFile( $confyaml ) |
|
57 | + or die( "$confyaml: $!\n" ); |
|
58 | + |
|
59 | +my $nodelistbaseyaml = './BrowseNodeIDs-JP.yaml'; |
|
60 | +my $nodelistbase = YAML::Syck::LoadFile( $nodelistbaseyaml ) |
|
61 | + or die( "$nodelistbaseyaml: $!\n" ); |
|
62 | + |
|
63 | +unless ( @ARGV ){ |
|
64 | + print "BrowseNodeId\tCategory\n"; |
|
65 | + foreach my $nodeid ( sort by_number ( keys( %{$nodelistbase} ) ) ){ |
|
66 | + print "$nodeid\t$nodelistbase->{$nodeid}\n"; |
|
67 | + } |
|
68 | + die( "usage: $0 <browse_node_id> [ <browse_node_id> ...]\n" ); |
|
69 | +} |
|
70 | +my $browsenodeid = join( ",", @ARGV ) || '465610'; |
|
71 | + |
|
72 | +my $u = URI::Amazon::APA->new( 'http://ecs.amazonaws.jp/onca/xml' ); |
|
73 | +$u->query_form( |
|
74 | + Service => 'AWSECommerceService', |
|
75 | + Operation => 'BrowseNodeLookup', |
|
76 | + ResponseGroup => 'BrowseNodeInfo', |
|
77 | + AssociateTag => $conf->{'ASSOCIATE_TAG'}, |
|
78 | + BrowseNodeId => $browsenodeid, |
|
79 | +); |
|
80 | +$u->sign( |
|
81 | + key => $conf->{'AWS_ACCESS_KEY_ID'}, |
|
82 | + secret => $conf->{'SECRET_ACCESS_KEY'}, |
|
83 | +); |
|
84 | + |
|
85 | +my $ua = LWP::UserAgent->new; |
|
86 | +my $r = $ua->get($u); |
|
87 | +if ( $r->is_success ){ |
|
88 | + my $content = XMLin( |
|
89 | + $r->content, |
|
90 | + ForceArray => [ 'BrowseNode', 'Error' ], |
|
91 | + KeyAttr => { 'BrowseNode' => '+BrowseNodeId' } |
|
92 | + ); |
|
93 | +# die( YAML::Syck::Dump( $content ) ); |
|
94 | + if ( my $errors = $content->{'BrowseNodes'}->{'Request'}->{'Errors'} ){ |
|
95 | + die( YAML::Syck::Dump( $errors ) ); |
|
96 | + } |
|
97 | + my $nodelist = $content->{'BrowseNodes'}->{'BrowseNode'}; |
|
98 | +# die( YAML::Syck::Dump( $nodelist ) ); |
|
99 | + foreach my $nodeid ( sort by_number ( keys( %{$nodelist} ) ) ){ |
|
100 | + my $node = $nodelist->{$nodeid}; |
|
101 | + print "Node\t\t$node->{'BrowseNodeId'}\t$node->{'Name'}\n"; |
|
102 | + printAncestors( $node ); |
|
103 | + my $children = $node->{'Children'}->{'BrowseNode'}; |
|
104 | + foreach my $childid ( sort by_number ( keys( %{$children} ) ) ){ |
|
105 | + my $child = $children->{$childid}; |
|
106 | + print "Child\t\t$child->{'BrowseNodeId'}\t$child->{'Name'}\n"; |
|
107 | + } |
|
108 | + } |
|
109 | +} else { |
|
110 | + die( $r->status_line, "\n" ); |
|
111 | +} |
|
112 | + |
|
113 | +exit; |
|
114 | + |
|
115 | +sub by_number |
|
116 | +{ |
|
117 | + $a <=> $b; |
|
118 | +} |
|
119 | + |
|
120 | +sub printAncestors |
|
121 | +{ |
|
122 | + my( $browsenode ) = @_; |
|
123 | + if ( my $ancestors = $browsenode->{'Ancestors'}->{'BrowseNode'} ){ |
|
124 | + foreach my $nodeid ( keys( %{$ancestors} ) ){ |
|
125 | + my $node = $ancestors->{$nodeid}; |
|
126 | + print "Ancestor\t$node->{'BrowseNodeId'}\t$node->{'Name'}\n"; |
|
127 | + printAncestors( $node ); |
|
128 | + } |
|
129 | + } |
|
130 | +} |
|
131 | + |
|
132 | +# EOF |
|
133 | +``` |
|
134 | + |
|
135 | +## エラーメッセージ対応 |
|
136 | +- XML::Simple で下記エラーメッセージが表示される。 |
|
137 | +``` |
|
138 | +could not find ParserDetails.ini in D:/Perl64/site/lib/XML/SAX |
|
139 | +``` |
|
140 | +- 次の行を追加する。 |
|
141 | +``` |
|
142 | +$XML::Simple::PREFERRED_PARSER = 'XML::Parser'; |
|
143 | +``` |
|
144 | + |
|
145 | +- [xml - Could not find ParserDetails.ini - Stack Overflow](https://stackoverflow.com/questions/%32%32%30%32%33%38%39%34) |
|
146 | + |
|
147 | +## リンク |
|
148 | +- [[Perl/XML-XPath]] |
|
149 | + |
|
150 | +- [CPAN:XML-Simple](http://search.cpan.org/dist/XML-Simple) |
|
151 | +- [CPAN:URI-Amazon-APA](http://search.cpan.org/dist/URI-Amazon-APA) |
|
152 | + |
|
153 | +- [Perl 開発者のための XML: 第 1 回 XML と Perl -- 魔法の組み合わせ](http://www.ibm.com/developerworks/jp/xml/library/x-xmlperl1.html) |
|
154 | +- [作って学ぶ、今どきのWebサービス: 第3回 XML::SimpleであらゆるXML文書を料理する](http://www.itmedia.co.jp/enterprise/articles/0702/26/news011.html) |
|
155 | +- [XML::Simple は遅い説における意外な落とし穴](http://iandeth.dyndns.org/mt/ian/archives/000589.html) |
|
156 | + |
|
157 | +- [PerlでAmazon Product Advertising APIのBrowseNodeLookupを行なう](http://tech.lampetty.net/tech/index.php/archives/338) |
|
... | ... | \ No newline at end of file |
Perl/Amazon/Home.md
... | ... | @@ -0,0 +1,21 @@ |
1 | +# Amazon Web Services |
|
2 | +[[_TOC_]] |
|
3 | +~~#ls2~~ |
|
4 | + |
|
5 | +## リンク |
|
6 | +- Amazon Web Services [日本語](http://aws.amazon.com/jp/) / [英語](http://aws.amazon.com/) |
|
7 | + - [Product Advertising API](https://affiliate.amazon.co.jp/gp/advertising/api/detail/main.html) |
|
8 | + - [Release Notes](http://aws.amazon.com/releasenotes/Product-Advertising-API) |
|
9 | + - [Product Advertising API Developer Guide](http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/) |
|
10 | + - [Anatomy of a REST Request (Locale Endpoint)](http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/AnatomyOfaRESTRequest.html) |
|
11 | + - [Browse Node IDs](http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/BrowseNodeIDs.html) |
|
12 | +<!----- [[Amazon E-Commerce Service API (2005-10-05):http://docs.amazonwebservices.com/AWSEcommerceService/2005-10-05/]]--> |
|
13 | +<!------ [[Browse Nodes for JP:http://docs.amazonwebservices.com/AWSEcommerceService/2005-10-05/ApiReference/JPBrowseNodesArticle.html]]--> |
|
14 | + - [ファイル名について](http://www.amazon.co.jp/gp/help/customer/display.html?ie=UTF8&nodeId=200129350) |
|
15 | + - [Amazon Web Services ブログ](http://aws.typepad.com/aws_japan/) |
|
16 | + - [Amazon アソシエイト (アフィリエイト)](https://affiliate.amazon.co.jp/) |
|
17 | +- [perl - URI::Amazon::APA released!](http://blog.livedoor.jp/dankogai/archives/51211577.html) |
|
18 | + - [CPAN:URI-Amazon-APA](http://search.cpan.org/dist/URI-Amazon-APA) |
|
19 | +- [Amazon Web サービス(AWS)の概要](http://www.rfs.jp/sb/perl/10/aws01.html) |
|
20 | +- [Shizラボ](http://shizlabs.amonya.com/) / [技術資料](http://shizlabs.amonya.com/tecnorogy/) / [Amazon商品画像のカスタマイズ(理論編)](http://shizlabs.amonya.com/amazon/image-uri01.html) |
|
21 | +- [PE2プレイ記録ほか](http://parasiteeve2.blog65.fc2.com/) / [Amazonの画像加工について(まとめ)](http://parasiteeve2.blog65.fc2.com/blog-entry-33.html) |
|
... | ... | \ No newline at end of file |
Perl/Amazon/getImages.md
... | ... | @@ -0,0 +1,346 @@ |
1 | +# 大きな画像を表示する |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- ASINから大きな画像のURIを求めて存在するかどうか確認する。 |
|
6 | +- 「content-type」が「image/jpeg」なら存在する、「image/gif」なら存在しない。 |
|
7 | + |
|
8 | +## 動作サンプル |
|
9 | +- [CGI Top](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi) |
|
10 | + - &amazon(B001EQ6A80);<br /> |
|
11 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B001EQ6A80) |
|
12 | + - &amazon(B002MZZ33K);<br /> |
|
13 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B002MZZ33K) |
|
14 | + - &amazon(B0026RIRRS);<br /> |
|
15 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B0026RIRRS) |
|
16 | + - &amazon(B002H9WBNQ);<br /> |
|
17 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B002H9WBNQ) |
|
18 | + - &amazon(B002L16FZU);<br /> |
|
19 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B002L16FZU) |
|
20 | + - &amazon(B0019JNTQS);<br /> |
|
21 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B0019JNTQS) |
|
22 | + - &amazon(B002SW3N16);<br /> |
|
23 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=B002SW3N16) |
|
24 | + - &amazon(4775307614);<br /> |
|
25 | +[画像一覧](http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN=4775307614&SHOT=IN) |
|
26 | + |
|
27 | +## Bookmarklet |
|
28 | +``` |
|
29 | +javascript:location='http://www.takeash.net/cgi-bin/Amazon/getImages.cgi?ASIN='+(location.href.match(/\/(dp|ASIN|product)\/([\w]+)/))[2]; |
|
30 | +``` |
|
31 | + |
|
32 | +## スクリプト |
|
33 | +- [getImages.zip](getImages.zip) |
|
34 | +```perl |
|
35 | +#!/usr/bin/perl |
|
36 | + |
|
37 | +use strict; |
|
38 | +use warnings; |
|
39 | +use utf8; |
|
40 | +use Encode; |
|
41 | +use LWP::UserAgent; |
|
42 | +use URI::Amazon::APA; |
|
43 | +use XML::Simple; |
|
44 | +use YAML::Syck; |
|
45 | +use CGI::Pretty qw( -no_xhtml *table *ol ); # //HTML 4.01 Transitional//EN |
|
46 | +use URI::Escape; |
|
47 | + |
|
48 | +$YAML::Syck::ImplicitUnicode = 1; |
|
49 | +$CGI::POST_MAX = 1024; |
|
50 | + |
|
51 | +binmode( STDIN, ":utf8" ); |
|
52 | +binmode( STDOUT, ":utf8" ); |
|
53 | +binmode( STDERR, ":utf8" ); |
|
54 | + |
|
55 | +# 自動フラッシュ有効化 (バッファリングを無効化) |
|
56 | +$| = 1; |
|
57 | + |
|
58 | +my $confyaml = './ID.yaml'; |
|
59 | +my $conf = YAML::Syck::LoadFile( $confyaml ) or die( "$confyaml: $!\n" ); |
|
60 | + |
|
61 | +my $cginame = 'Amazon getImages-JP'; |
|
62 | +my $ImageUriBase = |
|
63 | + 'http://images-jp.amazon.com/images/P/%ASIN%.09.%SHOT%._SC%SIZE%ZZZZZZ_.jpg'; |
|
64 | +my $NoImageUri = 'http://images-jp.amazon.com/images/G/09/nav2/dp/no-image-no-ciu.gif'; |
|
65 | +my $DetailUri = 'http://www.amazon.co.jp/dp/%ASIN%/'; |
|
66 | +my $CustomerImageUri = 'http://www.amazon.co.jp/gp/customer-media/product-gallery/%ASIN%'; |
|
67 | + |
|
68 | +my @ShotsFixList = ( |
|
69 | + { 'name' => 'Main', 'key' => 'MAIN', }, |
|
70 | + { 'name' => 'Top', 'key' => 'TOPP', }, |
|
71 | + { 'name' => 'Bottom', 'key' => 'BOTT', }, |
|
72 | + { 'name' => 'Left', 'key' => 'LEFT', }, |
|
73 | + { 'name' => 'Right', 'key' => 'RGHT', }, |
|
74 | + { 'name' => 'Front', 'key' => 'FRNT', }, |
|
75 | + { 'name' => 'Back', 'key' => 'BACK', }, |
|
76 | +); |
|
77 | + |
|
78 | +my @ShotsVarList = qw( PT IN ); |
|
79 | +my %ShotsTypeList = ( |
|
80 | + 0 => 'PIECE SHOTS / 書籍以外のその他の画像', |
|
81 | + 1 => 'INTERIOR SHOTS / 書籍のその他の画像', |
|
82 | +); |
|
83 | + |
|
84 | +my @SizeList = ( |
|
85 | + { 'name' => 'Large', 'key' => 'RM' }, |
|
86 | + { 'name' => 'Medium', 'key' => 'L' }, |
|
87 | +# { 'name' => 'Small', 'key' => 'M' }, |
|
88 | +); |
|
89 | + |
|
90 | +my $Step = 20; |
|
91 | +my %PageLabels = (); |
|
92 | +for( my $i=0; $i * $Step < 99; ++$i){ |
|
93 | + $PageLabels{ $i } = 'PT' . substr( '0' . ( $i * $Step + 1 ), -2 ) |
|
94 | + . '-PT'. substr( '0' . ( ( $i + 1 ) * $Step ), -2 ) |
|
95 | +} |
|
96 | +$PageLabels{ 0 } = 'Main, ' . $PageLabels{ 0 }; |
|
97 | +my $PageMax = @{ [ sort { $b <=> $a } ( keys( %PageLabels ) ) ] }[ 0 ]; |
|
98 | +$PageLabels{ $PageMax } =~ s/\d+$/99/; |
|
99 | + |
|
100 | +my $q = new CGI; |
|
101 | +$q->charset('utf-8'); |
|
102 | +my $cgipath = $q->url( -absolute => 1 ); |
|
103 | + |
|
104 | +my $URI = $q->param( 'URI' ) || ''; |
|
105 | +my $ASIN = ''; |
|
106 | +unless ( $ASIN = $q->param( 'ASIN' ) ){ |
|
107 | + # Perl 5.10 |
|
108 | + $URI =~ /\/(dp|ASIN|product)\/(?'asin'[\w]+)/; |
|
109 | + $ASIN = $+{asin}; |
|
110 | + # Perl 5.8 |
|
111 | + #$URI =~ /\/(dp|ASIN|product)\/([\w]+)/; |
|
112 | + #$ASIN = $2; |
|
113 | +} |
|
114 | +if ( $ASIN ){ |
|
115 | + $URI = $DetailUri; |
|
116 | + $URI =~ s/%ASIN%/$ASIN/; |
|
117 | +} |
|
118 | +my $SHOT = ( $q->param( 'SHOT' ) ) ? 1 : 0; |
|
119 | +my $shottype = $ShotsVarList[ $SHOT ]; |
|
120 | + |
|
121 | +my $PAGE = $q->param( 'PAGE' ) || 0; |
|
122 | +if ( $PAGE < 0 || $PageMax < $PAGE ){ |
|
123 | + $PAGE = 0; |
|
124 | +} |
|
125 | + |
|
126 | +my $MOD = $q->param( 'MOD' ) || 0; |
|
127 | + |
|
128 | +my $ua = LWP::UserAgent->new( keep_alive => ( 7 + $Step ) * 3 ); |
|
129 | + |
|
130 | +my @Anchors = (); |
|
131 | + |
|
132 | +printHeader(); |
|
133 | + |
|
134 | +if ( !$ASIN || $MOD ){ |
|
135 | + print $q->start_form( -action => $q->url ), |
|
136 | + $q->table( { -summary => 'enter ASIN and so on.', -border => 1 }, |
|
137 | + $q->Tr( |
|
138 | + $q->th( 'ASIN' ), |
|
139 | + $q->td( $q->textfield( -name => 'ASIN', -value => $ASIN ) ) |
|
140 | + ), |
|
141 | + $q->Tr( |
|
142 | + $q->th( 'URI' ), |
|
143 | + $q->td( $q->textfield( -name => 'URI', -value => $URI, -size => 80 ) ) |
|
144 | + ), |
|
145 | + $q->Tr( $q->th( 'SHOT' ), $q->td( $q->popup_menu( |
|
146 | + -name => 'SHOT', |
|
147 | + -values => [sort {$a<=>$b} keys(%ShotsTypeList)], |
|
148 | + -default => $SHOT, |
|
149 | + -labels => \%ShotsTypeList, |
|
150 | + ) ) ), |
|
151 | + $q->Tr( $q->th( 'PAGE' ), $q->td( $q->popup_menu( |
|
152 | + -name => 'PAGE', |
|
153 | + -values => [sort {$a<=>$b} keys(%PageLabels)], |
|
154 | + -default => $PAGE, |
|
155 | + -labels => \%PageLabels, |
|
156 | + ) ) ), |
|
157 | + $q->Tr( $q->td( |
|
158 | + { -colspan => 2, -align => 'center' }, |
|
159 | + $q->submit, " ", $q->reset |
|
160 | + ) ), |
|
161 | + ), |
|
162 | + $q->end_form; |
|
163 | +} else { |
|
164 | + my $u = URI::Amazon::APA->new( 'http://ecs.amazonaws.jp/onca/xml' ); |
|
165 | + $u->query_form( |
|
166 | + Service => 'AWSECommerceService', |
|
167 | + Operation => 'ItemLookup', |
|
168 | + ResponseGroup => 'ItemAttributes,Images', |
|
169 | + AssociateTag => $conf->{'ASSOCIATE_TAG'}, |
|
170 | + ItemId => $ASIN, |
|
171 | + ); |
|
172 | + $u->sign( |
|
173 | + key => $conf->{'AWS_ACCESS_KEY_ID'}, |
|
174 | + secret => $conf->{'SECRET_ACCESS_KEY'}, |
|
175 | + ); |
|
176 | + |
|
177 | + my $r = $ua->get($u); |
|
178 | + if ( $r->is_success ){ |
|
179 | + print $q->h2( 'Bibliography' ); |
|
180 | + my $content = XMLin( |
|
181 | + $r->content, |
|
182 | + ForceArray => [ |
|
183 | + 'Item', 'Error', 'DetailPageURL', 'SalesRank', 'ProductGroup', 'Title', |
|
184 | + ], |
|
185 | + KeyAttr => { 'Item' => '+ASIN', }, |
|
186 | + ); |
|
187 | + my( $title, $detailpageurl, $customerimage ); |
|
188 | + if ( my $errors = $content->{'Items'}->{'Request'}->{'Errors'}->{'Error'} ){ |
|
189 | + printErrors( $errors ); |
|
190 | + } else { |
|
191 | + my $items = $content->{'Items'}->{'Item'}; |
|
192 | + my $item = $items->{$ASIN}; |
|
193 | + $title = $item->{'ItemAttributes'}->{'Title'}; |
|
194 | + $detailpageurl = $item->{'DetailPageURL'}[0]; |
|
195 | + $detailpageurl = decode( 'utf8', uri_unescape( $detailpageurl ) ); |
|
196 | + # $detailpageurl =~ s#/[^/]+/(?=dp/)#/#; |
|
197 | + # $detailpageurl = uri_unescape( $detailpageurl ); |
|
198 | + $customerimage = $CustomerImageUri; |
|
199 | + $customerimage =~ s/%ASIN%/$ASIN/; |
|
200 | + } |
|
201 | + |
|
202 | + my $pagelabel = $PageLabels{ $PAGE }; |
|
203 | + $pagelabel =~ s/PT/$ShotsVarList[ $SHOT ]/g; |
|
204 | + print $q->table( { -summary => 'Bibliography', -border => 1 }, |
|
205 | + ( $title ) ? $q->Tr( |
|
206 | + $q->th( 'TITLE' ) , |
|
207 | + $q->td( |
|
208 | + $q->a( |
|
209 | + { -href => $detailpageurl || $URI . $conf->{'ASSOCIATE_TAG'} }, |
|
210 | + $title |
|
211 | + ), $q->br(), |
|
212 | + $q->a( { -href => $customerimage }, 'Customer Image' ) |
|
213 | + ) |
|
214 | + ) : '', |
|
215 | + $q->Tr( $q->th( 'ASIN' ), $q->td( $ASIN ) ), |
|
216 | + $q->Tr( $q->th( 'SHOT' ), $q->td( $ShotsTypeList{ $SHOT } ) ), |
|
217 | + $q->Tr( $q->th( 'PAGE' ), $q->td( $pagelabel ) ), |
|
218 | + ); |
|
219 | + |
|
220 | + print $q->h2( 'Search Results' ); |
|
221 | + $ImageUriBase =~ s/%ASIN%/$ASIN/; |
|
222 | + print $q->p( { -id => 'status' }, 'Now searching...' ); |
|
223 | + if ( $PAGE == 0 ){ |
|
224 | + foreach my $shot ( @ShotsFixList ){ |
|
225 | + my $ImageUri = $ImageUriBase; |
|
226 | + my $shotkey = $shot->{'key'}; |
|
227 | + $ImageUri =~ s/%SHOT%/$shotkey/; |
|
228 | + searchSize( $ImageUri, $shot->{'name'} ); |
|
229 | + } |
|
230 | + } |
|
231 | + for( my $i=$PAGE*$Step; $i<($PAGE+1)*$Step && $i<99; ++$i ){ |
|
232 | + my $ImageUri = $ImageUriBase; |
|
233 | + my $shotkey = $shottype . substr( '0' . ( $i + 1 ), -2 ); |
|
234 | + $ImageUri =~ s/%SHOT%/$shotkey/; |
|
235 | + searchSize( $ImageUri, $shotkey ); |
|
236 | + } |
|
237 | + if ( @Anchors ){ |
|
238 | + print $q->h2( $q->a( { -name => 'INDEX', -id => 'INDEX' }, 'Index' ) ), |
|
239 | + $q->start_ol(), |
|
240 | + $q->li( [ map { $q->a( { -href => '#' . $_ }, $_ ) } @Anchors ] ), |
|
241 | + $q->end_ol(); |
|
242 | + } else { |
|
243 | + print $q->p( $q->img( |
|
244 | + { -src => $NoImageUri, -title => 'No Image', -alt => 'No Image' } |
|
245 | + ) ); |
|
246 | + } |
|
247 | + print $q->p( $q->a( { -href => '#top', -name => 'bottom' }, 'Page Top' ) ); |
|
248 | + } else { |
|
249 | + print $q->p( $r->status_line ); |
|
250 | + } |
|
251 | +} |
|
252 | + |
|
253 | +printFooter(); |
|
254 | + |
|
255 | +exit; |
|
256 | + |
|
257 | +sub printHeader |
|
258 | +{ |
|
259 | + my $jscript = qq{ |
|
260 | + function changeStatus(){ |
|
261 | + document.getElementById('status').innerHTML = 'Finished.' |
|
262 | + + ( ( document.getElementById( 'INDEX' ) ) |
|
263 | + ? '<br><a href=\"#INDEX\">Index<'+'/a>' |
|
264 | + : '' ); |
|
265 | + } |
|
266 | + }; |
|
267 | + print $q->header(), |
|
268 | + $q->start_html( |
|
269 | + -title => $cginame, |
|
270 | + -lang => 'ja-JP', |
|
271 | + -head => [ |
|
272 | + $q->meta( { -http_equiv=>'Content-style-type', -content=>"text/css" } ), |
|
273 | + $q->meta( { -http_equiv=>'Content-script-type', -content=>"text/javascript" } ), |
|
274 | + ], |
|
275 | + -style => { 'src'=>'/take.css' }, |
|
276 | + -script => $jscript, |
|
277 | + -onLoad => 'changeStatus()', |
|
278 | + ), |
|
279 | + $q->h1( $q->a( { -name => 'top' }, $cginame ) ), |
|
280 | + $q->ul( |
|
281 | + $q->li( $q->a( { -href => $cgipath }, 'CGI Top' ) ), |
|
282 | + ( $ASIN && !$MOD ) |
|
283 | + ? $q->li( [ $q->a( { |
|
284 | + -href => "$cgipath?ASIN=$ASIN&SHOT=$SHOT&PAGE=$PAGE&MOD=1&URI=" |
|
285 | + . uri_escape_utf8( $URI ) |
|
286 | + }, 'Modify' ), ] ) |
|
287 | + : '', |
|
288 | + ); |
|
289 | +} |
|
290 | + |
|
291 | +sub printFooter |
|
292 | +{ |
|
293 | + print $q->end_html . "\n"; |
|
294 | +} |
|
295 | + |
|
296 | +sub printErrors |
|
297 | +{ |
|
298 | + my( $errors ) = @_; |
|
299 | +# print $q->h2( 'Error' ); |
|
300 | + print $q->start_table( { -summary => 'Error Message', -border => 1 } ); |
|
301 | + foreach my $error ( @{$errors} ){ |
|
302 | + print $q->Tr( $q->th( $error->{'Code'} ), $q->td( $error->{'Message'} ) ); |
|
303 | + } |
|
304 | + print $q->end_table(); |
|
305 | +} |
|
306 | + |
|
307 | +sub searchSize |
|
308 | +{ |
|
309 | + my( $ImageUriBase, $Shot ) = @_; |
|
310 | + foreach my $size ( @SizeList ){ |
|
311 | + my $ImageUri = $ImageUriBase; |
|
312 | + my $sizekey = $size->{'key'}; |
|
313 | + $ImageUri =~ s/%SIZE%/$sizekey/; |
|
314 | + my $title = $Shot . '_' . $size->{'name'}; |
|
315 | + #print $title . ': '; |
|
316 | + my $r = $ua->request( HTTP::Request->new( HEAD => $ImageUri ) ); |
|
317 | + if ( $r->header( 'content-type' ) eq 'image/jpeg' ){ |
|
318 | + #print 'Exist.' . $q->br(); |
|
319 | + print $q->p( |
|
320 | + $title, $q->a( { -name => $title, -href => '#INDEX' }, '*' ), $q->br(), |
|
321 | + $q->img( { -src => $ImageUri, -title => $title, -alt => $title, } ) |
|
322 | + ); |
|
323 | + push( @Anchors, $title ); |
|
324 | + last; |
|
325 | + } else { |
|
326 | + #print 'Not exist.' . $q->br(); |
|
327 | + } |
|
328 | + } |
|
329 | +} |
|
330 | + |
|
331 | +# EOF |
|
332 | +``` |
|
333 | + |
|
334 | +## リンク |
|
335 | +- [Shizラボ](http://shizlabs.amonya.com/) / [技術資料](http://shizlabs.amonya.com/tecnorogy/) / [Amazon商品画像のカスタマイズ(理論編)](http://shizlabs.amonya.com/amazon/image-uri01.html) |
|
336 | + |
|
337 | +- [PE2プレイ記録ほか](http://parasiteeve2.blog65.fc2.com/) |
|
338 | + - [Amazonの画像加工について(まとめ)](http://parasiteeve2.blog65.fc2.com/blog-entry-33.html) |
|
339 | + - [Amazonの画像加工(ツール編5)ASINから利用可能な全画像を求める・5](http://parasiteeve2.blog65.fc2.com/blog-entry-372.html) |
|
340 | + - [Amazonの画像加工(ツール編7)ASINから利用可能な全画像を求める・6](http://parasiteeve2.blog65.fc2.com/blog-entry-425.html) |
|
341 | + |
|
342 | +- [rubyu備忘録](http://d.hatena.ne.jp/ruby-U/) / [perlとpython用encodeURIComponent()](http://d.hatena.ne.jp/ruby-U/20081110/1226313786) |
|
343 | + |
|
344 | +- [CPAN:URI-Amazon-APA](http://search.cpan.org/dist/URI-Amazon-APA) |
|
345 | +- [CPAN:CGI](http://search.cpan.org/dist/CGI) |
|
346 | +- [CPAN:URI](http://search.cpan.org/dist/URI) / [CPAN:URI/URI/Escape.pm](http://search.cpan.org/dist/URI/URI/Escape.pm) |
|
... | ... | \ No newline at end of file |
Perl/ApacheErrorLogFormatter.md
... | ... | @@ -0,0 +1,202 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- Apache の error_log を HTML テーブルとして整形する。 |
|
5 | +- mod_security 対応。 |
|
6 | + |
|
7 | +# 動作サンプル |
|
8 | +- http://www.takeash.net/AELF/ |
|
9 | + |
|
10 | +# ソース |
|
11 | +- [AELF.zip](AELF.zip) |
|
12 | + |
|
13 | +## index.cgi |
|
14 | +```perl |
|
15 | +#!/usr/bin/perl |
|
16 | +# Apache のエラーログを整形 |
|
17 | + |
|
18 | +use strict; |
|
19 | +use warnings; |
|
20 | +use utf8; |
|
21 | +use Encode; |
|
22 | +use CGI::Pretty qw( -no_xhtml *table *ol ); |
|
23 | +use Net::DNS::Resolver; |
|
24 | + |
|
25 | +$CGI::POST_MAX = 80 * 1024; |
|
26 | + |
|
27 | +my $charsetConsole = 'UTF-8'; |
|
28 | +#my $charsetConsole = 'CP932'; |
|
29 | +my $charsetFile = 'UTF-8'; |
|
30 | + |
|
31 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
32 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
33 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
34 | + |
|
35 | +my $cgiName = 'Apache Error Log Formatter'; |
|
36 | + |
|
37 | +my @pair_type = ( |
|
38 | + { # mod_security |
|
39 | + header => qr/(ModSecurity:.*\.)\s(\[.*)\s*/, |
|
40 | + to_pair => qr/\[\S+\s[^\]]+\]\s*/, |
|
41 | + to_keyval => qr/\[(\S+)\s"([^\]]+)"\]\s*/, |
|
42 | + }, |
|
43 | + { # default, detail部無し |
|
44 | + header => qr/(.*)\s*/, |
|
45 | + }, |
|
46 | +); |
|
47 | + |
|
48 | +my $q = new CGI; |
|
49 | +$q->charset( $charsetFile ); |
|
50 | +my $br = $q->br(); |
|
51 | + |
|
52 | +my %processer = ( |
|
53 | + Client => \&toHostName, |
|
54 | + data => sub{ |
|
55 | + my $word = shift; |
|
56 | + $word =~ s/(\s(ARGS|ARGS_NAMES):)/$1$br/; |
|
57 | + return $word; |
|
58 | + }, |
|
59 | +); |
|
60 | + |
|
61 | +my $log = $q->param('LOG') || ''; |
|
62 | +if ( ( ! $ENV{'SERVER_ADDR'} ) && ( ! $log ) && ( my $file = $q->param('FILE') ) ){ |
|
63 | + open( my $IN, "<:encoding($charsetFile)", $file ) or die( "$file: $!\n" ); |
|
64 | + my @body = <$IN>; |
|
65 | + close( $IN ); |
|
66 | + $log = join( "", @body ); |
|
67 | +} |
|
68 | + |
|
69 | +print $q->header( |
|
70 | + -type => 'text/html', |
|
71 | + -charset => $charsetConsole, |
|
72 | +); |
|
73 | +print $q->start_html( |
|
74 | + -title => $cgiName, |
|
75 | + -head => [ |
|
76 | + $q->meta( { -http_equiv=>'Content-Type', -content=>"text/html; charset=" . $charsetConsole } ), |
|
77 | + $q->meta( { -http_equiv=>'Content-style-type', -content=>"text/css" } ), |
|
78 | + ], |
|
79 | + -style => [ { 'src'=>'/take.css' }, ], |
|
80 | +); |
|
81 | +print $q->h1( $cgiName ); |
|
82 | + |
|
83 | +if ( $log ){ |
|
84 | + print_result( $log ); |
|
85 | +} else { |
|
86 | + print_form(); |
|
87 | +} |
|
88 | + |
|
89 | +print $q->end_html . "\n"; |
|
90 | + |
|
91 | +exit; |
|
92 | + |
|
93 | +sub print_result |
|
94 | +{ |
|
95 | + my( $log ) = @_; |
|
96 | + $log =~ s/\r\n|\n\r/\n/gmx; |
|
97 | + $log =~ s/\r/\n/gmx; |
|
98 | + $log =~ s/"([^\"]*)"/'"'.encodeURIComponent($1).'"'/gmxe; |
|
99 | + |
|
100 | + print $q->p( $q->a( { -href => $q->url( -absolute => 1 ) }, 'form' ) ); |
|
101 | + |
|
102 | + my $index = 0; |
|
103 | + foreach my $line ( split( "\n", $log ) ){ |
|
104 | + if ( $line =~ /^\x{feff}?\s*$/ ){ |
|
105 | + next; |
|
106 | + } |
|
107 | +# print $q->h2( ++$index ); |
|
108 | + print $q->start_table( { -border => 1 } ); |
|
109 | +# print $q->Tr( $q->th( 'Line' ), $q->td( $line ) ); |
|
110 | + my( $datetime, $level, $client, $line2 ) = |
|
111 | + ( $line =~ /\[([^\]]+)\]\s\[([^\]]+)\](?:\s\[client\s([^\]]+)\])?\s*(.*)\s*$/ ); |
|
112 | + print $q->Tr( $q->th( 'Date Time' ), $q->td( $datetime ) ); |
|
113 | + print $q->Tr( $q->th( 'Level' ), $q->td( $level ) ); |
|
114 | + if ( $client ){ |
|
115 | + print $q->Tr( $q->th( 'Client' ), $q->td( toHostName( $client ) ) ); |
|
116 | + } |
|
117 | +# print $q->Tr( $q->th( 'Line2' ), $q->td( $line2 ) ); |
|
118 | + foreach my $type ( @pair_type ){ |
|
119 | + if ( $line2 =~ /^$type->{'header'}/ ){ |
|
120 | + my( $summary, $detail ) = ( $1, $2 ); |
|
121 | + $summary =~ s/([\.\,])\s/$1$br/; |
|
122 | + print $q->Tr( $q->th( 'Summary' ), $q->td( decodeURIComponent( $summary ) ) ); |
|
123 | + if ( $detail ){ |
|
124 | + foreach my $pair ( getPair( $type->{'to_pair'}, $type->{'to_keyval'}, $detail ) ){ |
|
125 | + my( $key, $val ) = ( $pair->[0], $pair->[1] ); |
|
126 | + if ( my $proc = $processer{$key} ){ |
|
127 | + $val = $proc->( $val ); |
|
128 | + } |
|
129 | + print $q->Tr( $q->th( $key ), $q->td( $val ) ); |
|
130 | + } |
|
131 | + } |
|
132 | + last; |
|
133 | + } |
|
134 | + } |
|
135 | + print $q->end_table(), $q->br(); |
|
136 | + } |
|
137 | + |
|
138 | + print $q->p( $q->a( { -href => $q->url( -absolute => 1 ) }, 'form' ) ); |
|
139 | +} |
|
140 | + |
|
141 | +sub getPair |
|
142 | +{ |
|
143 | + my( $to_pair, $to_keyval, $line ) = @_; |
|
144 | + my @ret = (); |
|
145 | +# print "'$to_pair'\n'$line'\n"; |
|
146 | + foreach my $pair ( $line =~ /$to_pair/g ){ |
|
147 | +# print "'$pair'\n"; |
|
148 | + my( $key, $val ) = ( $pair =~ /^$to_keyval$/ ); |
|
149 | + $val = decodeURIComponent( $val ); |
|
150 | + push( @ret, [ $key, $val ] ); |
|
151 | + } |
|
152 | + return @ret; |
|
153 | +} |
|
154 | + |
|
155 | +sub print_form |
|
156 | +{ |
|
157 | + print |
|
158 | + $q->start_form( -action => $q->url, -enctype => 'multipart/form-data' ), |
|
159 | + $q->submit, " ", $q->reset, $q->br(), |
|
160 | + $q->textarea( -name=>'LOG', -rows=>20, -columns=>80 ), |
|
161 | + $q->end_form; |
|
162 | +} |
|
163 | + |
|
164 | +sub encodeURIComponent |
|
165 | +{ |
|
166 | + my $str = encode( 'utf-8', shift ); |
|
167 | + $str =~ s/([^0-9A-Za-z!\x27()*\-._~])/sprintf("%%%02X", ord($1))/eg; # \x27 = ' |
|
168 | + return $str; |
|
169 | +} |
|
170 | + |
|
171 | +sub decodeURIComponent |
|
172 | +{ |
|
173 | + my $str = shift; |
|
174 | + $str =~ s/%([0-9A-F][0-9A-F])/pack( "H*", $1 )/egi; |
|
175 | + return decode( 'utf-8', $str ); |
|
176 | +} |
|
177 | + |
|
178 | +sub toHostName |
|
179 | +{ |
|
180 | + my $ip_address = shift || ''; |
|
181 | + my $ret = ''; |
|
182 | + |
|
183 | + my $resolver = Net::DNS::Resolver->new; |
|
184 | + if ( my $ans = $resolver->query( $ip_address ) ){ |
|
185 | + for my $rr ( $ans->answer ){ |
|
186 | + #print $rr->string, "\n"; |
|
187 | + if ( $rr->type eq 'PTR' ){ |
|
188 | + $ret = $rr->ptrdname; |
|
189 | + last; |
|
190 | + } |
|
191 | + } |
|
192 | + } |
|
193 | + |
|
194 | + return $ip_address . '; ' . $ret; |
|
195 | +} |
|
196 | + |
|
197 | +# EOF |
|
198 | +``` |
|
199 | + |
|
200 | +# リンク |
|
201 | +- [[Perl/MatchList]] |
|
202 | +- [[Linux/Apache]] |
|
... | ... | \ No newline at end of file |
Perl/AutoHashedFuncs.md
... | ... | @@ -0,0 +1,76 @@ |
1 | +# AutoHashedFuncs |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- 関数名を指定しなくても関数定義するだけで自動的にハッシュに登録されるサンプル。 |
|
6 | +- 型グロブを使って定義されている関数をスキャンする。 |
|
7 | + |
|
8 | +## ソース |
|
9 | +- [AutoHashedFuncs.zip](AutoHashedFuncs.zip) |
|
10 | +```Perl |
|
11 | +# 関数名を指定しなくても関数定義するだけで自動的にハッシュに登録される。 |
|
12 | + |
|
13 | +use strict; |
|
14 | +use warnings; |
|
15 | +use utf8; |
|
16 | +use Encode; |
|
17 | +use YAML::Syck; |
|
18 | + |
|
19 | +{ |
|
20 | + package MyDecoder; |
|
21 | + |
|
22 | + # 関数へのリファレンスが格納されるハッシュ |
|
23 | + our %Decoders = (); |
|
24 | + |
|
25 | + foreach my $key ( sort( keys( %MyDecoder:: ) ) ){ |
|
26 | + no strict "refs"; |
|
27 | + if ( $key =~ /decode(.*)/ && *{"MyDecoder::$key"}{CODE} ){ |
|
28 | + $Decoders{$1} = *{"MyDecoder::$key"}{CODE}; |
|
29 | + } |
|
30 | + } |
|
31 | + |
|
32 | + # 型グロブからアクセスできるけど CODE ではないので登録されない |
|
33 | + my $decode1 = "aaa"; |
|
34 | + my @decode2 = qw( bbb ccc ddd ); |
|
35 | + our $decode3 = "eee"; |
|
36 | + our @decode4 = qw( fff ggg hhh ); |
|
37 | + |
|
38 | + # 登録される |
|
39 | + sub decodeAdd { |
|
40 | + my( $a, $b ) = @_; |
|
41 | + return $a + $b; |
|
42 | + } |
|
43 | + |
|
44 | + # 登録される |
|
45 | + sub decodeMul { |
|
46 | + my( $a, $b ) = @_; |
|
47 | + return $a * $b; |
|
48 | + } |
|
49 | + |
|
50 | + # 関数名がルールから外れているので登録されない |
|
51 | + sub helper1 { |
|
52 | + my( $a, $b ) = @_; |
|
53 | + return $a - $b; |
|
54 | + } |
|
55 | +} |
|
56 | + |
|
57 | +# $main::refDecoders にリファレンスをコピーして使い易くする |
|
58 | +my $refDecoders = \%MyDecoder::Decoders; |
|
59 | + |
|
60 | +print Dump( $refDecoders ) . "\n"; |
|
61 | + |
|
62 | +for my $key ( qw( decode1 decode2 decode3 decode4 decodeAdd Add decodeMul Mul helper1 ) ){ |
|
63 | + if ( my $dc = $refDecoders->{$key} ){ |
|
64 | + print "$key:\t" . &{$dc}( 2, 4 ) . "\n"; |
|
65 | + } else { |
|
66 | + print "$key:\t-\n"; |
|
67 | + } |
|
68 | +} |
|
69 | + |
|
70 | +# EOF |
|
71 | +``` |
|
72 | + |
|
73 | +## リンク |
|
74 | +- [perldoc.jp](http://perldoc.jp/) / [Perlのリファレンスとネストしたデータ構造](http://perldoc.jp/pod/perlref) |
|
75 | + |
|
76 | +- [サンプルコードによるPerl入門](http://d.hatena.ne.jp/perlcodesample/) / [型グロブとシンボルテーブル](http://d.hatena.ne.jp/perlcodesample/20080614/1213428778) |
|
... | ... | \ No newline at end of file |
Perl/CGI.pm.md
... | ... | @@ -0,0 +1,266 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- CGI.pm のテストサンプル |
|
5 | +- [動作サンプル](http://www.takeash.net/cgi-bin/etc/testCGI.cgi) |
|
6 | +- フォームタグが閉じていなかったのを修正。(2012/10/02) |
|
7 | + |
|
8 | +# 注意点 |
|
9 | + |
|
10 | +## textfield や hidden などの値を加工してセットしても前の値が表示される |
|
11 | +```perl |
|
12 | +my $param1 = $q->param('param1'); |
|
13 | +++$param1; |
|
14 | +print $param1; |
|
15 | +print $q->textfield( -name => 'param1', -default => $param1 ); # 前の値のまま |
|
16 | +``` |
|
17 | +- 対応方法 |
|
18 | + 1. タグを表示する前に param で値をセットする。 |
|
19 | +```perl |
|
20 | +$q->param( 'param1', $somevalue ); # $q->param( -name => 'param1', -values => [ $somevalue ] ); |
|
21 | +``` |
|
22 | + - [つかのぺ](http://tuka.s12.xrea.com/) / [CGI.pm](http://tuka.s12.xrea.com/index.xcg?p=CGI.pm) |
|
23 | + 1. override を指定すると強制的に上書きできる。 |
|
24 | +```perl |
|
25 | +print $q->textfield( -name => 'param1', -default => $somevalue, -override => 1 ); |
|
26 | +``` |
|
27 | + |
|
28 | +## リストコンテキストでのパラメータ読み出し |
|
29 | +- セキュリティ上の問題のため、リストコンテキストで「$q->param('name')」を使うと警告が表示される。<br />リストコンテキストが必要な場合は代わりに「$q->multi_param('name')」を使う。 |
|
30 | +- [Fetching the value or values of a single named parameter](http://search.cpan.org/dist/CGI/lib/CGI.pod#Fetching_the_value_or_values_of_a_single_named_parameter) |
|
31 | + |
|
32 | +# ソース |
|
33 | +- [testCGI.zip](testCGI.zip) |
|
34 | +```perl |
|
35 | +#!/usr/bin/perl |
|
36 | +# |
|
37 | +# CGI.pm のテスト |
|
38 | + |
|
39 | +use strict; |
|
40 | +use warnings; |
|
41 | +use utf8; |
|
42 | +use Encode; |
|
43 | +use YAML::Syck; |
|
44 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
45 | +#use CGI::Carp qw/fatalsToBrowser warningsToBrowser/; |
|
46 | + |
|
47 | +$YAML::Syck::ImplicitUnicode = 1; |
|
48 | + |
|
49 | +binmode( STDIN, ":utf8" ); |
|
50 | +binmode( STDOUT, ":utf8" ); |
|
51 | +binmode( STDERR, ":utf8" ); |
|
52 | + |
|
53 | +my $cginame = 'testCGI'; |
|
54 | +my $cookiename = 'クッキー'; |
|
55 | +my $charset = 'utf-8'; |
|
56 | + |
|
57 | +# フォームのエンコーディングタイプ。 |
|
58 | +# CGI.pm Version 3.48 の param メソッドに影響する。 |
|
59 | +# 1: application/x-www-form-urlencoded, param メソッドでバイナリ文字列が返る。 |
|
60 | +# 0: multipart/form-data, param メソッドで utf8 フラグ付き文字列が返る。 |
|
61 | +my $enctype = 1; |
|
62 | + |
|
63 | +my $q = new CGI; |
|
64 | +$q->charset( $charset ); |
|
65 | + |
|
66 | +my %popupgroup = ( |
|
67 | + 'popup1' => 'ポップアップ1', 'popup2' => 'ポップアップ2', |
|
68 | + 'popup3' => 'ポップアップ3', 'popup4' => 'ポップアップ4', |
|
69 | +); |
|
70 | +my %scrollgroup = ( |
|
71 | + 'scroll1' => 'スクロール1', 'scroll2' => 'スクロール2', |
|
72 | + 'scroll3' => 'スクロール3', 'scroll4' => 'スクロール4', |
|
73 | + 'scroll5' => 'スクロール5', |
|
74 | +); |
|
75 | +my %checkgroup = ( |
|
76 | + 'check1'=>'チェック1', 'check2'=>'チェック2', |
|
77 | + 'check3'=>'チェック3', |
|
78 | +); |
|
79 | +my %radiogroup = ( |
|
80 | + 'radio1'=>'ラジオ1', 'radio2'=>'ラジオ2', |
|
81 | + 'radio3'=>'ラジオ3', |
|
82 | +); |
|
83 | + |
|
84 | +my @names; |
|
85 | +if ( $enctype ){ |
|
86 | + # 'application/x-www-form-urlencoded' |
|
87 | + @names = map{ decode( 'utf8', $_ ) } $q->param(); |
|
88 | +} else { |
|
89 | + # 'multipart/form-data' |
|
90 | + @names = $q->param(); |
|
91 | +} |
|
92 | + |
|
93 | +printHeader(); |
|
94 | + |
|
95 | +if ( @names ){ |
|
96 | + print $q->h2('Param'); |
|
97 | + print $q->start_table( { '-summary' => 'Parameters', '-border' => 1 } ); |
|
98 | + foreach my $name ( @names ){ |
|
99 | + if ( $enctype ){ |
|
100 | + # 'application/x-www-form-urlencoded' |
|
101 | + print $q->Tr( |
|
102 | + $q->th( $name ), |
|
103 | + $q->td( join( $q->br(), map{ decode( 'utf8', $_ ) } $q->param( encode( 'utf8', $name ) ) ) ) |
|
104 | + ); |
|
105 | + } else { |
|
106 | + # 'multipart/form-data' |
|
107 | + print $q->Tr( |
|
108 | + $q->th( $name ), |
|
109 | + $q->td( join( $q->br(), $q->param( $name ) ) ) |
|
110 | + ); |
|
111 | + } |
|
112 | + } |
|
113 | + print $q->end_table(); |
|
114 | + print $q->h2('Cookie'); |
|
115 | + print $q->start_table( { '-summary' => 'Cookie', '-border' => 1 } ); |
|
116 | + foreach my $cookiename ( $q->cookie() ){ |
|
117 | + print $q->Tr( |
|
118 | + $q->th( decode( 'utf8', $cookiename ) ), |
|
119 | + $q->td( join( $q->br(), map{ decode( 'utf8', $_ ) } $q->cookie( $cookiename ) ) ) |
|
120 | + ); |
|
121 | + } |
|
122 | + print $q->end_table(); |
|
123 | +} else { |
|
124 | + print $q->start_form( |
|
125 | + '-action' => $q->url, |
|
126 | + '-enctype' => ( |
|
127 | + ( $enctype ) |
|
128 | + ? 'application/x-www-form-urlencoded' |
|
129 | + : 'multipart/form-data' |
|
130 | + ), |
|
131 | + ); |
|
132 | + print $q->start_table( { '-summary' => 'Parameters', '-border' => 1 } ); |
|
133 | + print $q->Tr( |
|
134 | + $q->th( 'テキスト' ), |
|
135 | + $q->td( $q->textfield( |
|
136 | + '-name' => 'テキスト', |
|
137 | + '-value' => 'あいうえお漢字' |
|
138 | + ) ) |
|
139 | + ); |
|
140 | + print $q->Tr( |
|
141 | + $q->th( 'テキストエリア' ), |
|
142 | + $q->td( $q->textarea( |
|
143 | + '-name' => 'テキストエリア', |
|
144 | + '-default' => "予定表\n\x{20B9F}", |
|
145 | + '-rows' => 3, |
|
146 | + '-columns' => 20 |
|
147 | + ) ) |
|
148 | + ); |
|
149 | + print $q->Tr( |
|
150 | + $q->th( 'ポップアップ' ), |
|
151 | + $q->td( $q->popup_menu( |
|
152 | + '-name' => 'ポップアップ', |
|
153 | + '-values' => [ sort( keys( %popupgroup ) ) ], |
|
154 | + '-default' => ( sort( keys( %popupgroup ) ) )[0], |
|
155 | + '-labels' => \%popupgroup, |
|
156 | + ) ) |
|
157 | + ); |
|
158 | + print $q->Tr( |
|
159 | + $q->th( 'スクロール' ), |
|
160 | + $q->td( $q->scrolling_list( |
|
161 | + '-name' => 'スクロール', |
|
162 | + '-values' => [ sort( keys( %scrollgroup ) ) ], |
|
163 | + '-default' => ( sort( keys( %scrollgroup ) ) )[0], |
|
164 | + '-size' => 3, |
|
165 | + '-multiple' => 'true', |
|
166 | + '-labels' => \%scrollgroup, |
|
167 | + ) ) |
|
168 | + ); |
|
169 | + print $q->Tr( |
|
170 | + $q->th( 'チェックボックス' ), |
|
171 | + $q->td( $q->checkbox_group( |
|
172 | + '-name' => 'チェックボックス', |
|
173 | + '-values' => [ sort( keys( %checkgroup ) ) ], |
|
174 | + '-default' => ( sort( keys( %checkgroup ) ) )[0], |
|
175 | + '-linebreak' => 'true', |
|
176 | + '-labels' => \%checkgroup, |
|
177 | + ) ) |
|
178 | + ); |
|
179 | + print $q->Tr( |
|
180 | + $q->th( 'ラジオボタン' ), |
|
181 | + $q->td( $q->radio_group( |
|
182 | + '-name' => 'ラジオボタン', |
|
183 | + '-values' => [ sort( keys( %radiogroup ) ) ], |
|
184 | + '-default' => ( sort( keys( %radiogroup ) ) )[0], |
|
185 | + '-linebreak' => 'true', |
|
186 | + '-labels' => \%radiogroup, |
|
187 | + ) ) |
|
188 | + ); |
|
189 | + print $q->Tr( $q->td( |
|
190 | + { '-colspan' => 2, '-align' => 'center' }, |
|
191 | + $q->submit . ' ' . $q->reset |
|
192 | + ) ); |
|
193 | + print $q->end_table(); |
|
194 | + print $q->end_form; |
|
195 | +} |
|
196 | + |
|
197 | +printFooter(); |
|
198 | + |
|
199 | +exit; |
|
200 | + |
|
201 | +sub printHeader |
|
202 | +{ |
|
203 | + my $cookieval = decode( 'utf8', |
|
204 | + $q->cookie( encode( 'utf8', $cookiename ) ) || '' |
|
205 | + ); |
|
206 | + $cookieval .= 'あ'; |
|
207 | + my $cookie = $q->cookie( |
|
208 | + '-name' => encode( 'utf8', $cookiename ), |
|
209 | + '-value' => encode( 'utf8', $cookieval ), |
|
210 | + ); |
|
211 | + print $q->header( '-cookie' => [ $cookie ] ); |
|
212 | + print $q->start_html( |
|
213 | + '-title' => $cginame, |
|
214 | + '-lang' => 'ja-JP', |
|
215 | + '-head' => [ |
|
216 | + $q->meta( { '-http_equiv' => 'Content-style-type', '-content' => 'text/css' } ), |
|
217 | + $q->meta( { '-http_equiv' => 'Content-script-type', '-content' => 'text/javascript' } ), |
|
218 | + ], |
|
219 | + '-style' => [ { 'src' => '/take.css' }, ], |
|
220 | + ); |
|
221 | + print $q->h1( $cginame ); |
|
222 | +} |
|
223 | + |
|
224 | +sub printFooter |
|
225 | +{ |
|
226 | + print $q->end_html . "\n"; |
|
227 | +} |
|
228 | + |
|
229 | +# EOF |
|
230 | +``` |
|
231 | + |
|
232 | +# システム設定 |
|
233 | + |
|
234 | +## Windows Server 2012(IIS8) |
|
235 | +- IIS インストール時に、「CGI」「ISAPI 拡張」「要求フィルター」を有効にする。 |
|
236 | + - IPアドレスによるアクセス制限を行う場合は「IPおよびドメインの制限」も有効にする。 |
|
237 | +- IIS マネージャ |
|
238 | + - 「アプリケーションプール - DefaultAppPool - 詳細設定 - 32ビットアプリケーションの有効化」を「True」に設定する。 |
|
239 | + - 「Default Web Site」または該当フォルダ |
|
240 | + - 「ハンドラーマッピング」を開き、「スクリプトマップ」を追加する。 |
|
241 | +| 要求パス | *.cgi | |
|
242 | +| --- | --- | |
|
243 | +| 実行可能ファイル | C:\Perl\bin\perlis.dll | |
|
244 | +| 名前 | Perl CGI | |
|
245 | + - 「既定のドキュメント」を開き、「index.cgi」を追加する。 |
|
246 | + - 「要求フィルター」のアップロード許可最大サイズの既定値は30MB弱。 |
|
247 | + - 最大値を変更する場合は、「要求フィルター」から、「機能設定の編集」を開き、「許可されたコンテンツ最大長」を変更する。 |
|
248 | + - [IIS で要求フィルタリングを構成する](http://technet.microsoft.com/ja-jp/library/hh831621.aspx) |
|
249 | + - [要求フィルターの使用方法](http://technet.microsoft.com/ja-jp/library/dd939071.aspx) |
|
250 | + - [要求制限 <requestLimits>](http://technet.microsoft.com/ja-jp/library/ee431638.aspx) |
|
251 | + |
|
252 | +- Active Perl は 32bit 版をインストールする。 |
|
253 | + - 64bit 版は、「perlis.dll」が含まれていない。 |
|
254 | + - CGI.pm でのアップロードサイズ制限設定は $CGI::POST_MAX で行う。 |
|
255 | + |
|
256 | +# リンク |
|
257 | +- [[Perl/環境変数]] |
|
258 | + |
|
259 | +- [CPAN:CGI-Alternatives](http://search.cpan.org/dist/CGI-Alternatives) |
|
260 | +- [CPAN:Mojolicious](http://search.cpan.org/dist/Mojolicious) |
|
261 | + - [CPAN:Mojolicious/lib/Mojolicious/Lite.pm](http://search.cpan.org/dist/Mojolicious/lib/Mojolicious/Lite.pm) |
|
262 | + |
|
263 | +- [CPAN:CGI](http://search.cpan.org/dist/CGI) |
|
264 | +- [CPAN:Encode](http://search.cpan.org/dist/Encode) |
|
265 | + |
|
266 | +- [perl - use CGI; use Encode; # 非英語Webプログラミング3原則](http://blog.livedoor.jp/dankogai/archives/51227060.html) |
|
... | ... | \ No newline at end of file |
Perl/CPAN.md
... | ... | @@ -0,0 +1,169 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# CPAN |
|
4 | +## シェルを起動して対話的にインストール |
|
5 | +``` |
|
6 | +# perl -MCPAN -e shell |
|
7 | +``` |
|
8 | + |
|
9 | +## bash 等からインストール |
|
10 | +``` |
|
11 | +# perl -MCPAN -e "CPAN::Shell->install('Bundle::CPAN')" |
|
12 | +``` |
|
13 | + |
|
14 | +## 更新可能なパッケージ一覧の表示 |
|
15 | +``` |
|
16 | +# perl -MCPAN -e "CPAN::Shell->r" |
|
17 | +``` |
|
18 | + |
|
19 | +## 一括更新 |
|
20 | +``` |
|
21 | +# perl -MCPAN -e "CPAN::Shell->install(CPAN::Shell->r)" |
|
22 | +``` |
|
23 | +- 途中で Yes/No の確認を求められる。 |
|
24 | + |
|
25 | +## バージョンを指定してインストール |
|
26 | +``` |
|
27 | +# perl -MCPAN -e "CPAN::Shell->install('LEMBARK/FindBin-libs-1.55.tar.gz')" |
|
28 | +``` |
|
29 | +- [CPAN:FindBin-libs](http://search.cpan.org/dist/FindBin-libs) は Perl v5.10.0 以上が必要で v5.8.8 にはインストールできない。 |
|
30 | + |
|
31 | +## シェルでヒストリが効かない (Bundle::CPANをインストール) |
|
32 | +``` |
|
33 | +> install Bundle::CPAN |
|
34 | +``` |
|
35 | + |
|
36 | +## 強制的に再インストール |
|
37 | +- インストール済みであっても強制に再インストールするには「force」を付ける。 |
|
38 | +``` |
|
39 | +> force install Scalar::Util |
|
40 | +``` |
|
41 | +- 「IO::Socket::SSL」が下記エラーにてインストールできなかったら、依存する「Scalar::Util」を強制再インストールする。 |
|
42 | +``` |
|
43 | +Net::SSL from Crypt-SSLeay can't verify hostnames; either install IO::Socket::SSL or turn off verification by setting the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0 at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 51. |
|
44 | +``` |
|
45 | +  |
|
46 | +``` |
|
47 | +You need the XS Version of Scalar::Util for dualvar() support at Makefile.PL line 56. |
|
48 | +``` |
|
49 | + |
|
50 | +## 複数のパッケージをまとめてインストール |
|
51 | +- インストールしたいパッケージ名を書いた適当な *.pm ファイルを作成し、それをインストールする。 |
|
52 | +``` |
|
53 | +# cd ~ |
|
54 | +# perl -MCPAN -e "CPAN::Shell->install('Bundle::MyPackages')" |
|
55 | +``` |
|
56 | +- /root/Bundle/MyPackages.pm |
|
57 | +```perl |
|
58 | +package Bundle::MyPackages; |
|
59 | + |
|
60 | +use strict; |
|
61 | +use utf8; |
|
62 | +use vars qw( $VERSION ); |
|
63 | +$VERSION = "0.01"; |
|
64 | +1; |
|
65 | + |
|
66 | +=head1 CONTENTS |
|
67 | + |
|
68 | +Env |
|
69 | +Fatal |
|
70 | +Test::Warnings |
|
71 | +Test::Output |
|
72 | +Test::Deep |
|
73 | +Time::Piece |
|
74 | +CGI |
|
75 | +URI::Escape::XS |
|
76 | +File::Basename |
|
77 | +FindBin::libs |
|
78 | +Getopt::Long |
|
79 | +HTTP::Date |
|
80 | +JSON::XS |
|
81 | +Lingua::JA::Numbers |
|
82 | +Lingua::JA::Regular::Unicode |
|
83 | +Log::Dispatch |
|
84 | +MIME::Base64 |
|
85 | +Socket |
|
86 | +Net::IP |
|
87 | +Net::Wake |
|
88 | +Crypt::SSLeay |
|
89 | +Perl::Tidy |
|
90 | +String::Util |
|
91 | +Text::CSV_XS |
|
92 | +Text::xSV::Slurp |
|
93 | +XML::Simple |
|
94 | +XML::XPath |
|
95 | +enum::hash |
|
96 | +Attribute::Constant |
|
97 | +Number::Format |
|
98 | +PadWalker |
|
99 | +Term::Encoding |
|
100 | + |
|
101 | +=cut |
|
102 | +``` |
|
103 | +- [複数のCPANモジュールを一括インストール - Kawa.net 旧ゆうすけブログ (Yahoo!版)](http://blogs.yahoo.co.jp/kawa_kawa_kawa_kawa/650645.html) |
|
104 | + |
|
105 | +## インストール済みのモジュールのバージョン確認 |
|
106 | +- Linux |
|
107 | +``` |
|
108 | +# perl -M(モジュール名) -e 'print "$(モジュール名)::VERSION\n";' |
|
109 | +# perl -MJSON::Syck -e 'print "$JSON::Syck::VERSION\n";' |
|
110 | +``` |
|
111 | +- Win |
|
112 | +``` |
|
113 | +> perl -M(モジュール名) -e "print $(モジュール名)::VERSION;" |
|
114 | +> perl -MJSON::Syck -e "print $JSON::Syck::VERSION;" |
|
115 | +``` |
|
116 | + |
|
117 | +# cpanminus |
|
118 | +## インストール |
|
119 | +- yum |
|
120 | +``` |
|
121 | +# yum install perl-App-cpanminus |
|
122 | +``` |
|
123 | +- CPAN |
|
124 | +``` |
|
125 | +# perl -MCPAN -e "CPAN::Shell->install('App::cpanminus')" |
|
126 | +# cpanm App::cpanoutdated |
|
127 | +``` |
|
128 | + |
|
129 | +## cpanm 自身のアップグレード |
|
130 | +``` |
|
131 | +# cpanm --self-upgrade |
|
132 | +``` |
|
133 | + |
|
134 | +## 一括更新 |
|
135 | +``` |
|
136 | +# cpan-outdated | cpanm |
|
137 | +``` |
|
138 | + |
|
139 | +# ppm |
|
140 | +## 一括更新 |
|
141 | +``` |
|
142 | +> ppm upgrade --install |
|
143 | +``` |
|
144 | + |
|
145 | +## 複数のパッケージをまとめてインストール |
|
146 | +- パッケージを複数指定する。 |
|
147 | +``` |
|
148 | +> ppm install Env Fatal Test::Warnings Test::Output Test::Deep Time::Piece |
|
149 | +> ppm install CGI URI::Escape::XS File::Basename FindBin::libs Getopt::Long |
|
150 | +> ppm install HTTP::Date JSON::XS Lingua::JA::Numbers Lingua::JA::Regular::Unicode |
|
151 | +> ppm install Log::Dispatch MIME::Base64 Socket Net::IP Net::Wake Crypt::SSLeay Perl::Tidy |
|
152 | +> ppm install String::Util Text::CSV_XS Text::xSV::Slurp XML::Simple XML::XPath |
|
153 | +> ppm install enum::hash Attribute::Constant Number::Format PadWalker Term::Encoding |
|
154 | +``` |
|
155 | + |
|
156 | +# リンク |
|
157 | +- [CPAN:CPAN/lib/CPAN.pm](http://search.cpan.org/dist/CPAN/lib/CPAN.pm) |
|
158 | + |
|
159 | +- [CPAN:App-cpanminus](http://search.cpan.org/dist/App-cpanminus) |
|
160 | +- https://github.com/miyagawa/cpanminus |
|
161 | +- [perl-App-cpanminus](http://rpm.pbone.net/index.php3?stat=3&search=perl-App-cpanminus&srodzaj=3) |
|
162 | + |
|
163 | +- [CPAN:Module-CoreList/lib/Module/CoreList.pod](http://search.cpan.org/dist/Module-CoreList/lib/Module/CoreList.pod) |
|
164 | +- [$shibayu36->blog;](http://shibayu36.hatenablog.com/) |
|
165 | + - [perlであるモジュールがコアモジュールかどうか調べる;](http://shibayu36.hatenablog.com/entry/2014/03/08/115105) |
|
166 | + |
|
167 | +- [CPAN:ExtUtils-Install/lib/ExtUtils/Installed.pm](http://search.cpan.org/dist/ExtUtils-Install/lib/ExtUtils/Installed.pm) |
|
168 | +- [Using Perl](http://nozawashinichi.sakura.ne.jp/usingmt/) |
|
169 | + - [Perl インストールされているモジュールを出力するコマンド](http://nozawashinichi.sakura.ne.jp/usingmt/2014/03/perl-8.html) |
|
... | ... | \ No newline at end of file |
Perl/DBIx-Custom.md
... | ... | @@ -0,0 +1,177 @@ |
1 | +# DBIx::Custom |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- [CPAN:DBIx-Custom](http://search.cpan.org/dist/DBIx-Custom) を使用して MS SQL Server に対してクエリを実行するサンプル。 |
|
6 | +- Where 句に「:UserID{=}」とか付け加えたいとこだけど、「$dbi->not_exists」がうまく働いてなくて値無しだとハングアップするみたいだ。 |
|
7 | +- というか MS SQL Server の ODBC はハングアップし過ぎ。ちゃんとエラー出して止まってくれ。 |
|
8 | + |
|
9 | +## ソース |
|
10 | +- [DBIx-Custom.zip](DBIx-Custom.zip) |
|
11 | + |
|
12 | +### summarize.pl |
|
13 | +```perl |
|
14 | +#!/usr/bin/perl |
|
15 | +# DBIx::Custom サンプル |
|
16 | +# 注文履歴集計 MS SQL Server 用 |
|
17 | + |
|
18 | +use strict; |
|
19 | +use warnings; |
|
20 | +use utf8; |
|
21 | +use Encode; |
|
22 | +use YAML::Syck; |
|
23 | +use DBIx::Custom; |
|
24 | +use DateTime; |
|
25 | +use Text::xSV::Slurp qw( xsv_slurp ); |
|
26 | + |
|
27 | +$YAML::Syck::ImplicitUnicode = 1; |
|
28 | + |
|
29 | +my $charsetConsole = 'CP932'; |
|
30 | +#my $charsetFile = 'UTF-8'; |
|
31 | +my $charsetFile = 'CP932'; |
|
32 | + |
|
33 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
34 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
35 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
36 | + |
|
37 | +my $DB_Connect_yaml = './DB_Connect.yaml'; |
|
38 | +my $fnOders = './DB/Orders.txt'; |
|
39 | + |
|
40 | +my $start_date = '2012-08-20'; |
|
41 | +my $end_date = '2012-09-01'; |
|
42 | + |
|
43 | +my $DB_Connect = YAML::Syck::LoadFile( $DB_Connect_yaml ) |
|
44 | + or die( "$DB_Connect_yaml: $!\n" ); |
|
45 | +foreach( %{$DB_Connect} ){ |
|
46 | + $DB_Connect->{'DSN'} =~ s/_${_}_/$DB_Connect->{$_}/; |
|
47 | +} |
|
48 | + |
|
49 | +my $dbi = DBIx::Custom->connect( |
|
50 | + dsn => 'DBI:' . $DB_Connect->{'DSN'}, |
|
51 | + user => $DB_Connect->{'User'}, |
|
52 | + password => $DB_Connect->{'Password'}, |
|
53 | + option => $DB_Connect->{'Options'} |
|
54 | +); |
|
55 | + |
|
56 | +#insertOrderRandom(); |
|
57 | +#insertOrderFromFile(); |
|
58 | + |
|
59 | +my $Orders = getOrders( $start_date, $end_date ); |
|
60 | +print Dump( $Orders ); |
|
61 | +exit; |
|
62 | + |
|
63 | +sub getOrders |
|
64 | +{ |
|
65 | + my( $start_date, $end_date ) = @_; |
|
66 | + |
|
67 | + my $where = $dbi->where; |
|
68 | + $where->clause( [ 'and', ':OrderDateTime{>=}', ':OrderDateTime{<}' ] ); |
|
69 | + $where->param({ |
|
70 | + OrderDateTime => [ |
|
71 | + $start_date ? $start_date : '1900-01-01', # $dbi->not_exists だとハングアップする? |
|
72 | + $end_date ? $end_date : '9999-12-31', # $dbi->not_exists だとハングアップする? |
|
73 | + ], |
|
74 | + }); |
|
75 | + |
|
76 | + my $sortOrder = $dbi->order; |
|
77 | + $sortOrder->prepend( 'UserID', 'OrderDateTime' ); |
|
78 | + |
|
79 | + my $Orders = $dbi->select( |
|
80 | + table => 'Orders', |
|
81 | + column => [ |
|
82 | + '[Orders].[OrderDateTime]', '[Orders].[OrderQuantity]', # Orders |
|
83 | + '[Users].[UserID]', '[Users].[UserName]', # Users |
|
84 | + '[Items].[ItemName]', '[Items].[ItemUnitPrice]', # Items |
|
85 | + '[Items].[ItemUnitPrice] * [Orders].[OrderQuantity] as [SubTotalPrice]', # 追加計算 |
|
86 | + ], |
|
87 | + join => [ |
|
88 | + 'JOIN [Users] ON [Orders].[OrderUser] = [Users].[UserID]', |
|
89 | + 'JOIN [Items] ON [Orders].[OrderItem] = [Items].[ItemID]', |
|
90 | + ], |
|
91 | + where => $where, |
|
92 | + append => $sortOrder->to_string, |
|
93 | + )->all; |
|
94 | + |
|
95 | + return $Orders; |
|
96 | +} |
|
97 | + |
|
98 | +sub insertOrderRandom |
|
99 | +{ |
|
100 | + my $userMax = 5; |
|
101 | + my $itemMax = 7; |
|
102 | + my $quantityMax = 30; |
|
103 | + for( my $orderNum = 20; $orderNum > 0; --$orderNum ){ |
|
104 | + my $datetime = DateTime->new( |
|
105 | + time_zone => 'local', |
|
106 | + year => 2012, |
|
107 | + month => int( rand( 4 ) + 7 ), |
|
108 | + day => int( rand( 31 ) + 1 ), |
|
109 | + hour => int( rand( 10 ) + 9 ), |
|
110 | + minute => int( rand( 60 ) ), |
|
111 | + ); |
|
112 | + $dbi->insert( |
|
113 | + { |
|
114 | + OrderDateTime => $datetime->ymd('-') . ' ' . $datetime->hms(':'), |
|
115 | + OrderUser => int( rand( $userMax ) + 1 ), |
|
116 | + OrderItem => int( rand( $itemMax ) + 1 ), |
|
117 | + OrderQuantity => int( rand( $quantityMax ) + 1 ), |
|
118 | + }, |
|
119 | + table => 'Orders', |
|
120 | + ); |
|
121 | + } |
|
122 | +} |
|
123 | + |
|
124 | +sub insertOrderFromFile |
|
125 | +{ |
|
126 | + my @orders = readXSV( $fnOders, { sep_char => "\t" } ); |
|
127 | + foreach my $order ( @orders ){ |
|
128 | + delete $order->{'OrderID'}; # IDENTITY 列を追加しようとするとハングアップする。 |
|
129 | + $dbi->insert( |
|
130 | + $order, |
|
131 | + table => 'Orders', |
|
132 | + ); |
|
133 | + } |
|
134 | +} |
|
135 | + |
|
136 | +sub readXSV |
|
137 | +{ |
|
138 | + my( $fname, $opt ) = @_; |
|
139 | + $opt = { binary => 1, %{$opt} }; |
|
140 | + open( my $fhin, "<:encoding($charsetFile)", encode( $charsetConsole, $fname ) ) |
|
141 | + or die( "$fname: $!" ); |
|
142 | + my @body = <$fhin>; |
|
143 | + close( $fhin ); |
|
144 | + my $ret = xsv_slurp( |
|
145 | + string => join( "", @body ), |
|
146 | + text_csv => $opt, |
|
147 | + ); |
|
148 | + return ( ref( $ret ) eq 'ARRAY' ) |
|
149 | + ? @{ $ret } |
|
150 | + : $ret ; |
|
151 | +} |
|
152 | + |
|
153 | +# EOF |
|
154 | +``` |
|
155 | + |
|
156 | +### DB_Connect.yaml |
|
157 | +``` |
|
158 | +# DB接続情報 |
|
159 | +Driver: ODBC |
|
160 | +Server: localhost\SQLExpress,1433 # <サーバ名>\<インスタンス名>[,<ポート番号>] |
|
161 | +User: TestUser |
|
162 | +Password: "TestPass" # 記号を含む場合は""で括る。 |
|
163 | +DB: TestShop1 |
|
164 | +Trusted_Connection: No |
|
165 | +AutoTranslate: No |
|
166 | +Options: |
|
167 | + LongTruncOk: 1 |
|
168 | + LongReadLen: 8192 |
|
169 | +DSN: _Driver_:Driver={SQL Server}; Server={_Server_}; Database=_DB_; Trusted_Connection=_Trusted_Connection_; AutoTranslate=_AutoTranslate_; |
|
170 | +``` |
|
171 | + |
|
172 | +## リンク |
|
173 | +- [[DBIx::NamedParams|Perl/DBIx-NamedParams]] |
|
174 | + |
|
175 | +- [CPAN:DBIx-Custom](http://search.cpan.org/dist/DBIx-Custom) |
|
176 | + - [CPAN:DBIx-Custom/lib/DBIx/Custom/Where.pm](http://search.cpan.org/dist/DBIx-Custom/lib/DBIx/Custom/Where.pm) |
|
177 | + - [CPAN:DBIx-Custom/lib/DBIx/Custom/Order.pm](http://search.cpan.org/dist/DBIx-Custom/lib/DBIx/Custom/Order.pm) |
|
... | ... | \ No newline at end of file |
Perl/DBIx-NamedParams.md
... | ... | @@ -0,0 +1,825 @@ |
1 | +# DBIx::NamedParams |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- mysql でも prepare でプレースホルダとして ? じゃなく名前で指定できるようにする。 |
|
6 | +- 同じ名前を繰り返し使ってもエラーにならない。 |
|
7 | +- こっちより [CPAN:DBIx-Custom](http://search.cpan.org/dist/DBIx-Custom) の方が柔軟で高機能だなー。どうしたもんか。 |
|
8 | +- [CPAN:DBIx-NamedBinding](http://search.cpan.org/dist/DBIx-NamedBinding) に比べると、bind_param_ex の1回でバインドできるのと型指定できる点が勝ってるかな。 |
|
9 | + |
|
10 | +## 使用法 |
|
11 | +### スカラーのバインド |
|
12 | +- 「:名前-型」でスカラー値を bind する。 |
|
13 | +```perl |
|
14 | +my $sql_insert = qq{ |
|
15 | + INSERT INTO `Users` ( `ID`, `Name`, `Status`, `RegDate` ) |
|
16 | + VALUES ( NULL, :Name-VARCHAR, :State-INTEGER, :RegDate-DATETIME ); |
|
17 | +}; |
|
18 | +$sth_insert = $dbh->prepare_ex( $sql_insert ) or die( "$DBI::errstr\n" ); |
|
19 | +$sth_insert->bind_param_ex( { 'Name' => 'リオ', 'State' => 1, 'RegDate' => '2011-02-21 10:00' } ); |
|
20 | +$sth_insert->execute() or die( "$DBI::errstr\n" ); |
|
21 | +``` |
|
22 | + |
|
23 | +### 配列(個数指定あり)のバインド |
|
24 | +- 「:名前{個数}-型」で配列値を個数個分 bind する。 |
|
25 | +```perl |
|
26 | +my $sql_select = qq{ |
|
27 | + SELECT `ID`, `Name`, `Status`, `RegDate` |
|
28 | + FROM `Users` |
|
29 | + WHERE `Status` in ( :State{4}-INTEGER ); |
|
30 | +}; |
|
31 | +$sth_select = $dbh->prepare_ex( $sql_select ) or die( "$DBI::errstr\n" ); |
|
32 | +$sth_select->bind_param_ex( { 'State' => [ 1,2,4,8 ] } ); |
|
33 | +$sth_select->execute() or die( "$DBI::errstr\n" ); |
|
34 | +``` |
|
35 | + |
|
36 | +### 配列(個数指定なし)のバインド |
|
37 | +- 「:名前+-型」で配列値を配列要素個分 bind する。<br /> |
|
38 | +prepare_exの引数としてSQL文と共に割り当てるハッシュを指定する必要がある。 |
|
39 | +```perl |
|
40 | +my $sql_select = qq{ |
|
41 | + SELECT `ID`, `Name`, `Status`, `RegDate` |
|
42 | + FROM `Users` |
|
43 | + WHERE `Status` in ( :State+-INTEGER ); |
|
44 | +}; |
|
45 | +$sth_select = $dbh->prepare_ex( $sql_select, { 'State' => [ 1,2,4,8 ] } ) |
|
46 | + or die( "$DBI::errstr\n" ); |
|
47 | +$sth_select->execute() or die( "$DBI::errstr\n" ); |
|
48 | +``` |
|
49 | + |
|
50 | +### デバッグログの採取 |
|
51 | +- プレースホルダの解析結果、解析後の SQL 文、バインドされる値をログファイルに書き出します。 |
|
52 | +- ファイル名を省略すると、ホームディレクトリ(Linux: 環境変数 HOME, Windows: 環境変数 USERPROFILE)にログファイル(DBIx-NamedParams.log)が作られます。 |
|
53 | +``` |
|
54 | +DBIx::NamedParams::debug_log( 'testNamedParams.log' ); |
|
55 | +``` |
|
56 | + |
|
57 | +### DBD のデータタイプに対応する SQL タイプのハッシュ |
|
58 | +``` |
|
59 | +my %DrvTypeToSQLType = $dbh->driver_typename_map(); |
|
60 | +``` |
|
61 | +- [[MySQL の例|#MySQL_DataType_Map]] |
|
62 | +- [[MS SQL Server の例|#MSSQL_DataType_Map]] |
|
63 | + |
|
64 | +## 変更履歴 |
|
65 | +### 0.0.5 / 2011/09/28 |
|
66 | +- driver_typename_map メソッドが返すハッシュを調整。DB が MS SQL Server の場合、datetime および smalldatetime に対して DATE ではなく WVARCHAR を割り当てるようにした。 |
|
67 | + |
|
68 | +### 0.0.4 / 2011/09/17 |
|
69 | +- driver_typename_map メソッド追加。その DBD で使用できるデータタイプに対応する SQL タイプ名のハッシュを返す。 |
|
70 | +- デバッグログのファイル名を指定できるようにした。ログの体裁の調整。 |
|
71 | +- MS SQL Server 版のサンプルを作成。datetime 型にバインドするのに DATETIME じゃなくて WVARCHAR(VARCHAR) 使わなくちゃいけないなんて、そんなん考慮しとらんよ…。 |
|
72 | + |
|
73 | +### 0.0.3 / 2011/04/17 |
|
74 | +- 機能面での追加・変更はなし。 |
|
75 | +- 「use base;」を「use parent;」に変更。 |
|
76 | +- import にて、継承元である DBI の import を呼び出すようにしたけど、不要かも? |
|
77 | +- ソース内の関数の順序を呼び出し元と呼び出し先が近くになるように変更。 |
|
78 | +- _parse_ex にて、$repeat の既定値を '' から 0 に変更。 |
|
79 | +- bind_param_ex にて、「no warnings;」を「no warnings 'uninitialized';」に変更。 |
|
80 | +- bind_param_ex にて、$ref_hash が HASH であることを確認するようにした。 |
|
81 | + |
|
82 | +### 0.0.2 / 2011/03/07 |
|
83 | +- prepare_ex のときに @_NamedParams をクリアするようにした。 |
|
84 | + |
|
85 | +## ソース |
|
86 | +- [NamedParams.zip](NamedParams.zip) |
|
87 | + |
|
88 | +### NamedParams.pm |
|
89 | +```perl |
|
90 | +# DBI::db::prepare, DBI::st::bind_param を拡張する。 |
|
91 | +# http://www.TakeAsh.net/wiki/?Perl/DBIx-NamedParams |
|
92 | +# |
|
93 | +# prepare_ex では「:名前-型」形式のようにプレースホルダを書く。 |
|
94 | +# bind_param_ex では名前と値の対応を示すハッシュを渡す。 |
|
95 | + |
|
96 | +package DBIx::NamedParams; |
|
97 | + |
|
98 | +use strict; |
|
99 | +use warnings; |
|
100 | +use utf8; |
|
101 | +use Encode; |
|
102 | +use Carp qw( croak ); |
|
103 | +use parent qw( DBI ); |
|
104 | +use DBI::Const::GetInfoType; |
|
105 | +use Log::Dispatch; |
|
106 | +use POSIX qw( strftime ); |
|
107 | + |
|
108 | +use version; our $VERSION = qv( '0.0.5' ); |
|
109 | + |
|
110 | +( $ENV{'LANG'} || '' ) =~ /\.(.*)$/; # ja_JP.UTF-8 |
|
111 | +my $charsetConsole = $1 || 'CP932'; |
|
112 | +my $charsetFile = 'UTF-8'; |
|
113 | + |
|
114 | +my $_default_log_filename = ( $ENV{'HOME'} || $ENV{'USERPROFILE'} ); |
|
115 | +$_default_log_filename =~ s#\\#/#g; |
|
116 | +$_default_log_filename .= '/DBIx-NamedParams.log'; |
|
117 | + |
|
118 | +my %_SQL_TypeRefs = (); |
|
119 | +my %_SQL_TypeInvs = (); |
|
120 | +my $_SQL_Types = ""; |
|
121 | +my @_NamedParams = (); |
|
122 | +my $_index; |
|
123 | +my $_log = undef; |
|
124 | + |
|
125 | +sub import { |
|
126 | + DBI->import(); # 不要か? |
|
127 | + _init(); |
|
128 | + *{DBI::db::driver_typename_map} = \&driver_typename_map; |
|
129 | + *{DBI::db::prepare_ex} = \&prepare_ex; |
|
130 | + *{DBI::st::bind_param_ex} = \&bind_param_ex; |
|
131 | +} |
|
132 | + |
|
133 | +sub _init |
|
134 | +{ |
|
135 | + foreach( @{ $DBI::EXPORT_TAGS{sql_types} } ){ |
|
136 | + my $refFunc = \&{"DBI::$_"}; |
|
137 | + if ( /^SQL_(.*)$/i ){ |
|
138 | + $_SQL_TypeRefs{ $1 } = &{ $refFunc }; |
|
139 | + $_SQL_TypeInvs{ &{ $refFunc } } = $1; |
|
140 | + } |
|
141 | + } |
|
142 | + $_SQL_Types = all_sql_types(); |
|
143 | +} |
|
144 | + |
|
145 | +sub debug_log |
|
146 | +{ |
|
147 | + my( $filename ) = @_; |
|
148 | + $filename = encode( $charsetConsole, ( $filename || $_default_log_filename ) ); |
|
149 | + $_log = Log::Dispatch->new( |
|
150 | + outputs => [ [ |
|
151 | + 'File', |
|
152 | + min_level => 'debug', |
|
153 | + filename => $filename, |
|
154 | + binmode => ":encoding($charsetFile)", |
|
155 | + permissions => 0666, |
|
156 | + newline => 1, |
|
157 | + ], ], |
|
158 | + ); |
|
159 | + $_log->info( _thisFuncName(), strftime( "%Y-%m-%d %H:%M:%S", localtime ) ); |
|
160 | +} |
|
161 | + |
|
162 | +sub _thisFuncName |
|
163 | +{ |
|
164 | + ( caller( 1 ) )[3] =~ /([^:]+)$/; |
|
165 | + return $1; |
|
166 | +} |
|
167 | + |
|
168 | +sub all_sql_types |
|
169 | +{ |
|
170 | + return wantarray |
|
171 | + ? sort( keys( %_SQL_TypeRefs ) ) |
|
172 | + : join( "|", sort( keys( %_SQL_TypeRefs ) ) ); |
|
173 | +} |
|
174 | +sub driver_typename_map |
|
175 | +{ |
|
176 | + my( $self ) = @_; |
|
177 | + my %map = (); |
|
178 | + foreach my $refType ( $self->type_info() ){ |
|
179 | + my $datatype = $refType->{ 'SQL_DATA_TYPE' } # MS SQL Server |
|
180 | + || $refType->{ 'SQL_DATATYPE' }; # MySQL |
|
181 | + $map{ $refType->{ 'TYPE_NAME' } } = $_SQL_TypeInvs{ $datatype } || 'WVARCHAR'; |
|
182 | + } |
|
183 | + if ( $self->get_info( $GetInfoType{ 'SQL_DBMS_NAME' } ) eq 'Microsoft SQL Server' ){ |
|
184 | + $map{ 'datetime' } = 'WVARCHAR'; |
|
185 | + $map{ 'smalldatetime' } = 'WVARCHAR'; |
|
186 | + } |
|
187 | + return %map; |
|
188 | +} |
|
189 | + |
|
190 | +sub prepare_ex |
|
191 | +{ |
|
192 | + my( $self, $sqlex, $refHash ) = @_; |
|
193 | + my $ret = undef; |
|
194 | + my $validHash = defined( $refHash ) && ref( $refHash ) eq 'HASH'; |
|
195 | + if ( $sqlex =~ /\:([\w]+)\+-($_SQL_Types)\b/ ){ |
|
196 | + if ( $validHash ){ |
|
197 | + $sqlex =~ s/\:([\w]+)\+-($_SQL_Types)\b/_parse_ex1($refHash,$1,$2);/ge; |
|
198 | + } else { |
|
199 | + croak( "prepare_ex need a hash reference when SQL is variable length.\n" ); |
|
200 | + } |
|
201 | + } |
|
202 | + @_NamedParams = (); |
|
203 | + $_index = 1; |
|
204 | + $sqlex =~ s/\:([\w]+)(?:\{(\d+)\})?-($_SQL_Types)\b/_parse_ex2($1,$2,$3);/ge; |
|
205 | + if ( $_log ){ |
|
206 | + $_log->info( _thisFuncName(), 'sql_raw', "{{$sqlex}}" ); |
|
207 | + } |
|
208 | + $ret = $self->prepare( $sqlex ) or croak( "$DBI::errstr" ); |
|
209 | + if ( $validHash ){ |
|
210 | + $ret->bind_param_ex( $refHash ); |
|
211 | + } |
|
212 | + return $ret; |
|
213 | +} |
|
214 | + |
|
215 | +sub _parse_ex1 |
|
216 | +{ |
|
217 | + my( $refHash, $name, $type ) = @_; |
|
218 | + return ":${name}{" . scalar( @{ $refHash->{ $name } } ) . "}-$type"; |
|
219 | +} |
|
220 | + |
|
221 | +sub _parse_ex2 |
|
222 | +{ |
|
223 | + my $name = shift || ''; |
|
224 | + my $repeat = shift || 0; |
|
225 | + my $type = shift || ''; |
|
226 | + my $ret = ''; |
|
227 | + # '' や 0 も有効値として使いたい場合 (Perl 5.9 以降) |
|
228 | + # my $param = shift // -1; |
|
229 | + if ( $_log ){ |
|
230 | + $_log->info( |
|
231 | + _thisFuncName(), |
|
232 | + "[$_index]", |
|
233 | + "\"$name\"", |
|
234 | + (!$repeat) ? "scalar" : "array[$repeat]", |
|
235 | + $type |
|
236 | + ); |
|
237 | + } |
|
238 | + if ( !$repeat ){ |
|
239 | + # scalar |
|
240 | + $_NamedParams[ $_index++ ] = { |
|
241 | + Name => $name, |
|
242 | + Type => $_SQL_TypeRefs{ $type }, |
|
243 | + Array => -1, |
|
244 | + }; |
|
245 | + $ret = '?'; |
|
246 | + } else { |
|
247 | + # array |
|
248 | + for( my $i=0; $i<$repeat; ++$i ){ |
|
249 | + $_NamedParams[ $_index++ ] = { |
|
250 | + Name => $name, |
|
251 | + Type => $_SQL_TypeRefs{ $type }, |
|
252 | + Array => $i, |
|
253 | + }; |
|
254 | + } |
|
255 | + $ret = substr( '?,' x $repeat, 0, -1 ); |
|
256 | + } |
|
257 | + return $ret; |
|
258 | +} |
|
259 | + |
|
260 | +sub bind_param_ex |
|
261 | +{ |
|
262 | + no warnings 'uninitialized'; |
|
263 | + my( $self, $refHash ) = @_; |
|
264 | + if ( !defined( $refHash ) || ref( $refHash ) ne 'HASH' ){ |
|
265 | + croak( "bind_param_ex need a hash reference.\n" ); |
|
266 | + } |
|
267 | + my $thisFunc = _thisFuncName(); |
|
268 | + for( my $i=1; $i<@_NamedParams; ++$i ){ |
|
269 | + my $idx = $_NamedParams[ $i ]{ 'Array' }; |
|
270 | + my $value1 = $refHash->{ $_NamedParams[ $i ]{ 'Name' } }; |
|
271 | + my $value2 = ( $idx < 0 || ref( $value1 ) ne 'ARRAY' ) |
|
272 | + ? $value1 |
|
273 | + : @{ $value1 }[ $idx ]; |
|
274 | + my $datatype = $_NamedParams[ $i ]{ 'Type' }; |
|
275 | + if ( $_log ){ |
|
276 | + $_log->info( |
|
277 | + $thisFunc, "[$i]", "\"$value2\"", $_SQL_TypeInvs{ $datatype } |
|
278 | + ); |
|
279 | + } |
|
280 | + $self->bind_param( $i, $value2 , { TYPE => $datatype } ) |
|
281 | + or croak( "$DBI::errstr\n" ); |
|
282 | + } |
|
283 | + return $self; |
|
284 | +} |
|
285 | + |
|
286 | +1; |
|
287 | + |
|
288 | +# EOF |
|
289 | +``` |
|
290 | + |
|
291 | +### testNamedParams_MySQL.pl |
|
292 | +```perl |
|
293 | +#!/usr/bin/perl |
|
294 | +# DBIx::NamedParams のテスト |
|
295 | + |
|
296 | +use strict; |
|
297 | +use warnings; |
|
298 | +use utf8; |
|
299 | +use Encode; |
|
300 | +use YAML::Syck; |
|
301 | +use POSIX qw( strftime ); |
|
302 | +use FindBin::libs; |
|
303 | +use lib qw( /home/Shared/lib ); |
|
304 | +use DBIx::NamedParams; |
|
305 | + |
|
306 | +( $ENV{'LANG'} || '' ) =~ /\.(.*)$/; # ja_JP.UTF-8 |
|
307 | +my $charsetConsole = $1 || 'CP932'; |
|
308 | +my $charsetFile = 'UTF-8'; |
|
309 | + |
|
310 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
311 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
312 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
313 | + |
|
314 | +$YAML::Syck::ImplicitUnicode = 1; |
|
315 | + |
|
316 | +my $path = $FindBin::RealBin . '/'; |
|
317 | +my $yaml = $path . 'DB_Connect_MySQL.yml'; |
|
318 | +my $input = $path . 'InputData.yml'; |
|
319 | + |
|
320 | +my $DB_Info = YAML::Syck::LoadFile( $yaml ) or die( "$yaml: $!\n" ); |
|
321 | +foreach( keys( %{$DB_Info} ) ){ |
|
322 | + $DB_Info->{'DSN'} =~ s/_${_}_/$DB_Info->{$_}/; |
|
323 | +} |
|
324 | + |
|
325 | +my $dbh = DBI->connect( |
|
326 | + 'DBI:' . $DB_Info->{'DSN'}, |
|
327 | + $DB_Info->{'User'}, |
|
328 | + $DB_Info->{'Password'}, |
|
329 | + $DB_Info->{'Options'} |
|
330 | +) or die( "$DBI::errstr\n" ); |
|
331 | + |
|
332 | +#DBIx::NamedParams::debug_log( 'testNamedParams.log' ); |
|
333 | + |
|
334 | +#my %DrvTypeToSQLType = $dbh->driver_typename_map(); |
|
335 | +#print Dump( \%DrvTypeToSQLType ); |
|
336 | + |
|
337 | +my $sql_insert = qq{ |
|
338 | + INSERT INTO |
|
339 | + `Users` |
|
340 | + ( `Name`, `Status`, `RegDate` ) |
|
341 | + VALUES |
|
342 | + ( :Name-VARCHAR, :State-INTEGER, :Now-DATETIME ); |
|
343 | +}; |
|
344 | + |
|
345 | +my $sth_insert = $dbh->prepare_ex( $sql_insert ) or die( "$DBI::errstr\n" ); |
|
346 | + |
|
347 | +my $users = YAML::Syck::LoadFile( $input ) or die( "$input: $!\n" ); |
|
348 | +#print Dump( $users ); |
|
349 | +#exit; |
|
350 | + |
|
351 | +foreach( @{$users} ){ |
|
352 | + $_->{'Now'} = strftime( "%Y-%m-%d %H:%M:%S", localtime ); |
|
353 | + print Dump( $_ ); |
|
354 | + $sth_insert->bind_param_ex( $_ ); |
|
355 | + $sth_insert->execute() or die( "$DBI::errstr\n" ); |
|
356 | + sleep( 1 ); |
|
357 | +} |
|
358 | +$sth_insert->finish; |
|
359 | + |
|
360 | +my $sql_select = qq{ |
|
361 | + SELECT |
|
362 | + `ID`, `Name`, `Status`, `RegDate` |
|
363 | + FROM |
|
364 | + `Users` |
|
365 | + WHERE |
|
366 | + `Status` in ( :State+-INTEGER ); |
|
367 | +}; |
|
368 | + |
|
369 | +my $sth_select = $dbh->prepare_ex( $sql_select, { 'State' => [ 1,2,5 ] } ) |
|
370 | + or die( "$DBI::errstr\n" ); |
|
371 | +$sth_select->execute() or die( "$DBI::errstr\n" ); |
|
372 | +do { |
|
373 | + no warnings 'uninitialized'; |
|
374 | + while( my @a = $sth_select->fetchrow_array ){ |
|
375 | + printf( "%s\n", join( "\t", @a ) ); |
|
376 | + } |
|
377 | +}while( $sth_select->{odbc_more_results} ); |
|
378 | +$sth_select->finish; |
|
379 | + |
|
380 | +$dbh->disconnect; |
|
381 | + |
|
382 | +exit; |
|
383 | + |
|
384 | +# EOF |
|
385 | +``` |
|
386 | + |
|
387 | +### DB_Connect_MySQL.yml |
|
388 | +``` |
|
389 | +# DB接続情報 |
|
390 | +Driver: mysql |
|
391 | +Server: localhost |
|
392 | +Port: 3306 |
|
393 | +User: TestUser |
|
394 | +Password: "Test" # 記号を含む場合は""で括る |
|
395 | +DB: TestDB |
|
396 | +Options: |
|
397 | + mysql_enable_utf8: 1 |
|
398 | +DSN: "_Driver_:database=_DB_; host=_Server_; port=_Port_;" # Linux |
|
399 | +#DSN: "_Driver_:database=_DB_:host=_Server_" # Windows |
|
400 | +``` |
|
401 | + |
|
402 | +### createUsers_MySQL.sql |
|
403 | +```sql |
|
404 | +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; |
|
405 | + |
|
406 | +CREATE TABLE `Users` ( |
|
407 | + `ID` int(11) NOT NULL AUTO_INCREMENT, |
|
408 | + `Name` varchar(40) NOT NULL, |
|
409 | + `Status` int(11) NOT NULL DEFAULT '0', |
|
410 | + `RegDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
|
411 | + PRIMARY KEY (`ID`) |
|
412 | +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; |
|
413 | +``` |
|
414 | + |
|
415 | +### InputData.yml (MySQL/MSSQL 共通) |
|
416 | +``` |
|
417 | +--- |
|
418 | +- { Name: リオ, State: 1 } |
|
419 | +- { Name: ミント, State: 2 } |
|
420 | +- { Name: ローザ, State: 3 } |
|
421 | +- { Name: リンダ, State: 4 } |
|
422 | +- { Name: リナ, State: 5 } |
|
423 | +- { Name: アーニャ, State: 6 } |
|
424 | +``` |
|
425 | + |
|
426 | +### testNamedParams_MSSQL.pl |
|
427 | +```perl |
|
428 | +#!/usr/bin/perl |
|
429 | +# DBIx::NamedParams のテスト |
|
430 | + |
|
431 | +use strict; |
|
432 | +use warnings; |
|
433 | +use utf8; |
|
434 | +use Encode; |
|
435 | +use YAML::Syck; |
|
436 | +use POSIX qw( strftime ); |
|
437 | +use FindBin::libs; |
|
438 | +use lib qw( /home/Shared/lib ); |
|
439 | +use DBIx::NamedParams; |
|
440 | + |
|
441 | +( $ENV{'LANG'} || '' ) =~ /\.(.*)$/; # ja_JP.UTF-8 |
|
442 | +my $charsetConsole = $1 || 'CP932'; |
|
443 | +my $charsetFile = 'UTF-8'; |
|
444 | + |
|
445 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
446 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
447 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
448 | + |
|
449 | +$YAML::Syck::ImplicitUnicode = 1; |
|
450 | + |
|
451 | +my $path = $FindBin::RealBin . '/'; |
|
452 | +my $yaml = $path . 'DB_Connect_MSSQL.yml'; |
|
453 | +my $input = $path . 'InputData.yml'; |
|
454 | + |
|
455 | +my $DB_Info = YAML::Syck::LoadFile( $yaml ) or die( "$yaml: $!\n" ); |
|
456 | +foreach( keys( %{$DB_Info} ) ){ |
|
457 | + $DB_Info->{'DSN'} =~ s/_${_}_/$DB_Info->{$_}/; |
|
458 | +} |
|
459 | + |
|
460 | +my $dbh = DBI->connect( |
|
461 | + 'DBI:' . $DB_Info->{'DSN'}, |
|
462 | + $DB_Info->{'User'}, |
|
463 | + $DB_Info->{'Password'}, |
|
464 | + $DB_Info->{'Options'} |
|
465 | +) or die( "$DBI::errstr\n" ); |
|
466 | + |
|
467 | +#DBIx::NamedParams::debug_log( 'testNamedParams.log' ); |
|
468 | + |
|
469 | +#my %DrvTypeToSQLType = $dbh->driver_typename_map(); |
|
470 | +#print Dump( \%DrvTypeToSQLType ); |
|
471 | + |
|
472 | +my $sql_insert = qq{ |
|
473 | + INSERT INTO |
|
474 | + [Users] |
|
475 | + ( [Name], [Status], [RegDate] ) |
|
476 | + VALUES |
|
477 | + ( :Name-WVARCHAR, :State-INTEGER, :Now-WVARCHAR ); |
|
478 | +}; |
|
479 | + |
|
480 | +my $sth_insert = $dbh->prepare_ex( $sql_insert ) or die( "$DBI::errstr\n" ); |
|
481 | + |
|
482 | +my $users = YAML::Syck::LoadFile( $input ) or die( "$input: $!\n" ); |
|
483 | +#print Dump( $users ); |
|
484 | +#exit; |
|
485 | + |
|
486 | +foreach( @{$users} ){ |
|
487 | + $_->{'Now'} = strftime( "%Y-%m-%d %H:%M:%S", localtime ); |
|
488 | + print Dump( $_ ); |
|
489 | + $sth_insert->bind_param_ex( $_ ); |
|
490 | + $sth_insert->execute() or die( "$DBI::errstr\n" ); |
|
491 | + sleep( 1 ); |
|
492 | +} |
|
493 | +$sth_insert->finish; |
|
494 | + |
|
495 | +my $sql_select = qq{ |
|
496 | + SELECT |
|
497 | + [ID], [Name], [Status], [RegDate] |
|
498 | + FROM |
|
499 | + [Users] |
|
500 | + WHERE |
|
501 | + [Status] in ( :State+-INTEGER ); |
|
502 | +}; |
|
503 | + |
|
504 | +my $sth_select = $dbh->prepare_ex( $sql_select, { 'State' => [ 1,2,5 ] } ) |
|
505 | + or die( "$DBI::errstr\n" ); |
|
506 | +$sth_select->execute() or die( "$DBI::errstr\n" ); |
|
507 | +do { |
|
508 | + no warnings 'uninitialized'; |
|
509 | + while( my @a = $sth_select->fetchrow_array ){ |
|
510 | + printf( "%s\n", join( "\t", @a ) ); |
|
511 | + } |
|
512 | +}while( $sth_select->{odbc_more_results} ); |
|
513 | +$sth_select->finish; |
|
514 | + |
|
515 | +$dbh->disconnect; |
|
516 | + |
|
517 | +exit; |
|
518 | + |
|
519 | +# EOF |
|
520 | +``` |
|
521 | + |
|
522 | +### DB_Connect_MSSQL.yml |
|
523 | +``` |
|
524 | +# DB接続情報 |
|
525 | +Driver: ODBC |
|
526 | +Server: localhost\SQLExress,1433 # <サーバ名>\<インスタンス名>[,<ポート>] |
|
527 | +User: TestUser |
|
528 | +Password: "Test" # 記号を含む場合は""で括る |
|
529 | +DB: TestDB |
|
530 | +Options: |
|
531 | + LongTruncOk: 1 |
|
532 | + LongReadLen: 8192 |
|
533 | +DSN: _Driver_:Driver={SQL Server}; Server={_Server_}; Database=_DB_; |
|
534 | +``` |
|
535 | + |
|
536 | +### createUsers_MSSQL.sql |
|
537 | +```sql |
|
538 | +USE [TestDB] |
|
539 | +GO |
|
540 | + |
|
541 | +SET ANSI_NULLS ON |
|
542 | +GO |
|
543 | + |
|
544 | +SET QUOTED_IDENTIFIER ON |
|
545 | +GO |
|
546 | + |
|
547 | +CREATE TABLE [dbo].[Users]( |
|
548 | + [ID] [int] IDENTITY(1,1) NOT NULL, |
|
549 | + [Name] [nvarchar](40) NOT NULL, |
|
550 | + [Status] [int] NOT NULL, |
|
551 | + [RegDate] [datetime] NULL, |
|
552 | + CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED |
|
553 | + ( |
|
554 | + [ID] ASC |
|
555 | + ) WITH ( |
|
556 | + PAD_INDEX = OFF, |
|
557 | + STATISTICS_NORECOMPUTE = OFF, |
|
558 | + IGNORE_DUP_KEY = OFF, |
|
559 | + ALLOW_ROW_LOCKS = ON, |
|
560 | + ALLOW_PAGE_LOCKS = ON |
|
561 | + ) ON [PRIMARY] |
|
562 | +) ON [PRIMARY] |
|
563 | +GO |
|
564 | + |
|
565 | +ALTER TABLE [dbo].[Users] |
|
566 | +ADD CONSTRAINT [DF_Users_RegDate] |
|
567 | +DEFAULT (getdate()) FOR [RegDate] |
|
568 | +GO |
|
569 | +``` |
|
570 | + |
|
571 | +## SQLTypes |
|
572 | +### getSQLTypes.pl |
|
573 | +```perl |
|
574 | +# SQLタイプ一覧 |
|
575 | + |
|
576 | +use strict; |
|
577 | +use warnings; |
|
578 | +use utf8; |
|
579 | +use Encode; |
|
580 | +use POSIX qw( strftime ); |
|
581 | +use FindBin::libs; |
|
582 | +use lib qw( /home/Shared/lib ); |
|
583 | +use DBIx::NamedParams; |
|
584 | + |
|
585 | +print "Perl version: " . $] . "\n"; |
|
586 | +print "DBI version: " . $DBI::VERSION . "\n"; |
|
587 | +print strftime( "%Y-%m-%d %H:%M:%S\n\n", localtime ); |
|
588 | +print join( "\n", DBIx::NamedParams::all_sql_types() ) . "\n"; |
|
589 | + |
|
590 | +# EOF |
|
591 | +``` |
|
592 | + |
|
593 | +### 出力 |
|
594 | +``` |
|
595 | +Perl version: 5.010001 |
|
596 | +DBI version: 1.616 |
|
597 | +2011-06-17 00:37:32 |
|
598 | + |
|
599 | +ALL_TYPES |
|
600 | +ARRAY |
|
601 | +ARRAY_LOCATOR |
|
602 | +BIGINT |
|
603 | +BINARY |
|
604 | +BIT |
|
605 | +BLOB |
|
606 | +BLOB_LOCATOR |
|
607 | +BOOLEAN |
|
608 | +CHAR |
|
609 | +CLOB |
|
610 | +CLOB_LOCATOR |
|
611 | +DATE |
|
612 | +DATETIME |
|
613 | +DECIMAL |
|
614 | +DOUBLE |
|
615 | +FLOAT |
|
616 | +GUID |
|
617 | +INTEGER |
|
618 | +INTERVAL |
|
619 | +INTERVAL_DAY |
|
620 | +INTERVAL_DAY_TO_HOUR |
|
621 | +INTERVAL_DAY_TO_MINUTE |
|
622 | +INTERVAL_DAY_TO_SECOND |
|
623 | +INTERVAL_HOUR |
|
624 | +INTERVAL_HOUR_TO_MINUTE |
|
625 | +INTERVAL_HOUR_TO_SECOND |
|
626 | +INTERVAL_MINUTE |
|
627 | +INTERVAL_MINUTE_TO_SECOND |
|
628 | +INTERVAL_MONTH |
|
629 | +INTERVAL_SECOND |
|
630 | +INTERVAL_YEAR |
|
631 | +INTERVAL_YEAR_TO_MONTH |
|
632 | +LONGVARBINARY |
|
633 | +LONGVARCHAR |
|
634 | +MULTISET |
|
635 | +MULTISET_LOCATOR |
|
636 | +NUMERIC |
|
637 | +REAL |
|
638 | +REF |
|
639 | +ROW |
|
640 | +SMALLINT |
|
641 | +TIME |
|
642 | +TIMESTAMP |
|
643 | +TINYINT |
|
644 | +TYPE_DATE |
|
645 | +TYPE_TIME |
|
646 | +TYPE_TIMESTAMP |
|
647 | +TYPE_TIMESTAMP_WITH_TIMEZONE |
|
648 | +TYPE_TIME_WITH_TIMEZONE |
|
649 | +UDT |
|
650 | +UDT_LOCATOR |
|
651 | +UNKNOWN_TYPE |
|
652 | +VARBINARY |
|
653 | +VARCHAR |
|
654 | +WCHAR |
|
655 | +WLONGVARCHAR |
|
656 | +WVARCHAR |
|
657 | +``` |
|
658 | + |
|
659 | +## MySQLのデータタイプ |
|
660 | +``` |
|
661 | +--- |
|
662 | +bigint: BIGINT |
|
663 | +bigint auto_increment: BIGINT |
|
664 | +bigint unsigned: BIGINT |
|
665 | +bigint unsigned auto_increment: BIGINT |
|
666 | +bit: BIT |
|
667 | +bit auto_increment: BIT |
|
668 | +blob: LONGVARBINARY |
|
669 | +char: CHAR |
|
670 | +date: DATE |
|
671 | +datetime: TIMESTAMP |
|
672 | +decimal: NUMERIC |
|
673 | +double: DOUBLE |
|
674 | +double auto_increment: DOUBLE |
|
675 | +enum: ALL_TYPES |
|
676 | +float: FLOAT |
|
677 | +float auto_increment: FLOAT |
|
678 | +int: INTEGER |
|
679 | +int auto_increment: INTEGER |
|
680 | +int unsigned: INTEGER |
|
681 | +int unsigned auto_increment: INTEGER |
|
682 | +integer: INTEGER |
|
683 | +integer auto_increment: INTEGER |
|
684 | +integer unsigned: INTEGER |
|
685 | +integer unsigned auto_increment: INTEGER |
|
686 | +long varbinary: LONGVARBINARY |
|
687 | +long varchar: LONGVARCHAR |
|
688 | +longblob: LONGVARBINARY |
|
689 | +mediumblob: LONGVARBINARY |
|
690 | +mediumint: INTEGER |
|
691 | +mediumint auto_increment: INTEGER |
|
692 | +mediumint unsigned: INTEGER |
|
693 | +mediumint unsigned auto_increment: INTEGER |
|
694 | +mediumtext: LONGVARCHAR |
|
695 | +numeric: NUMERIC |
|
696 | +set: ALL_TYPES |
|
697 | +smallint: SMALLINT |
|
698 | +smallint auto_increment: SMALLINT |
|
699 | +smallint unsigned: SMALLINT |
|
700 | +smallint unsigned auto_increment: SMALLINT |
|
701 | +text: LONGVARCHAR |
|
702 | +time: TIME |
|
703 | +timestamp: TIMESTAMP |
|
704 | +tinyblob: VARBINARY |
|
705 | +tinyint: TINYINT |
|
706 | +tinyint auto_increment: TINYINT |
|
707 | +tinyint unsigned: TINYINT |
|
708 | +tinyint unsigned auto_increment: TINYINT |
|
709 | +varchar: VARCHAR |
|
710 | +year: SMALLINT |
|
711 | +``` |
|
712 | + |
|
713 | +## MS SQL Server のデータタイプ |
|
714 | +``` |
|
715 | +--- |
|
716 | +bigint: BIGINT |
|
717 | +bigint identity: BIGINT |
|
718 | +binary: BINARY |
|
719 | +bit: BIT |
|
720 | +char: CHAR |
|
721 | +date: WVARCHAR |
|
722 | +datetime: WVARCHAR |
|
723 | +datetime2: WVARCHAR |
|
724 | +datetimeoffset: WVARCHAR |
|
725 | +decimal: DECIMAL |
|
726 | +decimal() identity: DECIMAL |
|
727 | +float: FLOAT |
|
728 | +image: LONGVARBINARY |
|
729 | +int: INTEGER |
|
730 | +int identity: INTEGER |
|
731 | +money: DECIMAL |
|
732 | +nchar: WCHAR |
|
733 | +ntext: WLONGVARCHAR |
|
734 | +numeric: NUMERIC |
|
735 | +numeric() identity: NUMERIC |
|
736 | +nvarchar: WVARCHAR |
|
737 | +real: REAL |
|
738 | +smalldatetime: WVARCHAR |
|
739 | +smallint: SMALLINT |
|
740 | +smallint identity: SMALLINT |
|
741 | +smallmoney: DECIMAL |
|
742 | +sql_variant: WVARCHAR |
|
743 | +sysname: WVARCHAR |
|
744 | +text: LONGVARCHAR |
|
745 | +time: WVARCHAR |
|
746 | +timestamp: BINARY |
|
747 | +tinyint: TINYINT |
|
748 | +tinyint identity: TINYINT |
|
749 | +uniqueidentifier: GUID |
|
750 | +varbinary: VARBINARY |
|
751 | +varchar: VARCHAR |
|
752 | +xml: WLONGVARCHAR |
|
753 | +``` |
|
754 | + |
|
755 | +## リンク |
|
756 | +- [[DBIx::Custom|Perl/DBIx-Custom]] |
|
757 | + |
|
758 | +- [安全なウェブサイトの作り方](http://www.ipa.go.jp/security/vuln/websecurity.html) 安全なSQLの呼び出し方 |
|
759 | + |
|
760 | +- http://perldoc.jp/ |
|
761 | + - [perlobj - Perl のオブジェクト](http://perldoc.jp/docs/perl/5.10.0/perlobj.pod) |
|
762 | + - [perlmod - Perl のモジュール (パッケージとシンボルテーブル)](http://perldoc.jp/docs/perl/5.10.0/perlmod.pod) |
|
763 | + |
|
764 | +- [ダウンロードたけし(寅年)の日記](http://d.hatena.ne.jp/download_takeshi/) |
|
765 | + - [DBIでbindした後のSQL文を引っ張り出す方法](http://d.hatena.ne.jp/download_takeshi/20081209/1228837813) |
|
766 | + - [DBI/Executed.pm](http://coderepos.org/share/browser/lang/perl/DBI-Executed/trunk/lib/DBI/Executed.pm) |
|
767 | + |
|
768 | +- [ブログが続かないわけ](http://en.yummy.stripper.jp/) |
|
769 | + - [[Perl][微エロ注意]画像収集のときにいつも同じイディオムを書いているのをやめたい](http://en.yummy.stripper.jp/?eid=1159981) |
|
770 | + |
|
771 | +- [404 Blog Not Found](http://blog.livedoor.jp/dankogai/) |
|
772 | + - [perl - use Carp; # warn() と die() だけじゃなくて](http://blog.livedoor.jp/dankogai/archives/51073468.html) |
|
773 | + - [perl - no warnings 'unintialized'](http://blog.livedoor.jp/dankogai/archives/50622749.html) |
|
774 | + - [perl - デフォルト値のperlらしい指定法](http://blog.livedoor.jp/dankogai/archives/51074877.html) |
|
775 | + - [perl - 継承を使いたいワケ](http://blog.livedoor.jp/dankogai/archives/50706327.html) |
|
776 | + |
|
777 | +- [サンプルコードによるPerl入門](http://d.hatena.ne.jp/perlcodesample/) |
|
778 | + - [Exporter - 関数のエクスポート / Perlモジュール徹底解説](http://d.hatena.ne.jp/perlcodesample/20100426/1270894115) |
|
779 | + - [柔軟なSQL / DBIx::Customの特徴](http://d.hatena.ne.jp/perlcodesample/20110118/1300165343) |
|
780 | + - [DBIx::Connectorを利用する / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110123/1300165343) |
|
781 | + - [DBIx::Connectorによるトランザクション処理 / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110125/1300165343) |
|
782 | + - [行の挿入 insert / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110129/1300165343) |
|
783 | + - [行の更新 update / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110130/1300165343) |
|
784 | + - [DBIx::Customの紹介(1) - モデル](http://d.hatena.ne.jp/perlcodesample/20110131/1300165343) |
|
785 | + - [すべての行の更新 update_all / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110201/1300165343) |
|
786 | + - [行の削除 delete / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110202/1300165343) |
|
787 | + - [すべての行の削除 delete_all / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110203/1300165343) |
|
788 | + - [Where句で日付の範囲を指定する / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110204/1300165343) |
|
789 | + - [予約語を使用している列やテーブルに対応する / DBIx::Custom Tips](http://d.hatena.ne.jp/perlcodesample/20110207/1300165343) |
|
790 | + - [DBIx::Customの特徴(2) SQLの知識がそのまま利用できる](http://d.hatena.ne.jp/perlcodesample/20110208/1300165343) |
|
791 | + |
|
792 | +- [Islands in the byte stream](http://d.hatena.ne.jp/gfx/) |
|
793 | + - [Don't use base.pm, use parent.pm instead!](http://d.hatena.ne.jp/gfx/20101226/1293342019) |
|
794 | + |
|
795 | +- [Perl-users.jp](http://perl-users.jp/) |
|
796 | + - [Perl 5 今昔](http://perl-users.jp/nowpast.html) |
|
797 | + - [使っちゃいけない標準モジュール - JPerl advent calendar 2010 casual Track](http://perl-users.jp/articles/advent-calendar/2010/casual/23) |
|
798 | + |
|
799 | +- [Part1 正しいPerl/CGIの書き方 - Webプログラミング実力アップ:ITpro](http://itpro.nikkeibp.co.jp/article/COLUMN/20071011/284280/) Module::Starter::PBP によるモジュール開発例 |
|
800 | + |
|
801 | +- [楽:技林ブログ](http://tech.bayashi.jp/) |
|
802 | + - [はじめてのPerlモジュール開発メモ/楽](http://tech.bayashi.jp/archives/entry/perl/2008/002326.html) |
|
803 | + |
|
804 | +- [個人的なメモのページ](http://www12.atpages.jp/~lottz/pukiwikiplus/) |
|
805 | + - [Perl_Modules](http://www12.atpages.jp/~lottz/pukiwikiplus/index.php?Perl_Modules) |
|
806 | + |
|
807 | +- [CPAN:DBI](http://search.cpan.org/dist/DBI) |
|
808 | +- [CPAN:DBD-mysql](http://search.cpan.org/dist/DBD-mysql) |
|
809 | +- [CPAN:DBD-ODBC](http://search.cpan.org/dist/DBD-ODBC) |
|
810 | + |
|
811 | +- [CPAN:DBIx-Custom](http://search.cpan.org/dist/DBIx-Custom) |
|
812 | + - [CPAN:DBIx-Custom/lib/DBIx/Custom/Guide/Ja.pod](http://search.cpan.org/dist/DBIx-Custom/lib/DBIx/Custom/Guide/Ja.pod) |
|
813 | + - [DBIx::Custom Wiki - GitHub](https://github.com/yuki-kimoto/DBIx-Custom/wiki) |
|
814 | +- [CPAN:DBIx-NamedBinding](http://search.cpan.org/dist/DBIx-NamedBinding) |
|
815 | +- [CPAN:DBIx-Simple](http://search.cpan.org/dist/DBIx-Simple) |
|
816 | +- [CPAN:DBIx-InsertHash](http://search.cpan.org/dist/DBIx-InsertHash) |
|
817 | + |
|
818 | +- [CPAN:perl/lib/Carp.pm](http://search.cpan.org/dist/perl/lib/Carp.pm) |
|
819 | +- [CPAN:parent](http://search.cpan.org/dist/parent) |
|
820 | +- [CPAN:base](http://search.cpan.org/dist/base) |
|
821 | +- [CPAN:Log-Dispatch](http://search.cpan.org/dist/Log-Dispatch) |
|
822 | + |
|
823 | +- [CPAN:perl](http://search.cpan.org/dist/perl) POSIX strftime |
|
824 | + |
|
825 | +- [CPAN:FindBin-libs](http://search.cpan.org/dist/FindBin-libs) |
|
... | ... | \ No newline at end of file |
Perl/EPS\343\203\225\343\202\241\343\202\244\343\203\253\344\275\234\346\210\220/Home.md
... | ... | @@ -0,0 +1,24 @@ |
1 | +# EPSファイル作成 |
|
2 | +[[_TOC_]] |
|
3 | +~~#ls2~~ |
|
4 | +---- |
|
5 | +## 幾何学図形と文字 |
|
6 | +### 概要 |
|
7 | +- 使用しているフォントは「小塚明朝 Std - M」。 |
|
8 | +- EPS中で「Shift_JIS」で指定する場合は「KozMinStd-Medium-90ms-RKSJ-H」と記述する。(横書き) |
|
9 | +- 画像の埋め込みは行っていない。 |
|
10 | + |
|
11 | +### ダウンロード |
|
12 | +- ソースコードと出力されるEPSファイル<br /> |
|
13 | +[createEPS.zip](createEPS.zip) |
|
14 | +- EPSファイルをAcrobat Distiller 6でPDFに変換したもの<br /> |
|
15 | +[ToneChart.pdf](ToneChart.pdf) |
|
16 | + |
|
17 | +## リンク |
|
18 | +- [[Typography_PDF|etc/Typography_PDF]] |
|
19 | +- [[文字コード|Perl/文字コード]] |
|
20 | + |
|
21 | +- [CPAN:PostScript-Simple](http://search.cpan.org/dist/PostScript-Simple) |
|
22 | +- [CPAN:Font-TTF](http://search.cpan.org/dist/Font-TTF) / [Manual](http://search.cpan.org/dist/Font-TTF/lib/Font/TTF/Manual.pod) |
|
23 | + |
|
24 | +- [中島 靖](http://hp1.jonex.ne.jp/~nakajima.yasushi/) / [PDFJ - 日本語PDF生成モジュール](http://hp1.jonex.ne.jp/~nakajima.yasushi/PDFJ.jp.html) |
|
... | ... | \ No newline at end of file |
Perl/EPS\343\203\225\343\202\241\343\202\244\343\203\253\344\275\234\346\210\220/SimpleEPS.md
... | ... | @@ -0,0 +1,41 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- 単純なEPSの例。 |
|
5 | +- ドキュメントサイズ: 200 x 200pt (70.6 x 70.6 mm) |
|
6 | +- 背景: M20% |
|
7 | +- 文字: 小塚明朝Pro Regular, 36pt |
|
8 | +- 文字コード: UTF-8, BOM無し (BOMを付けるとDistillerでエラーとなる) |
|
9 | +- 改行コード: CRLF |
|
10 | + |
|
11 | +# ソース |
|
12 | +- [Simple.zip](Simple.zip) |
|
13 | +``` |
|
14 | +%!PS-Adobe-3.0 EPSF-3.0 |
|
15 | +%%BoundingBox: 0 0 200 200 |
|
16 | +%%EndComments |
|
17 | + |
|
18 | +%%BeginProlog |
|
19 | +%%EndProlog |
|
20 | + |
|
21 | +%%Page: 1 1 |
|
22 | + |
|
23 | +% Frame |
|
24 | +0 0 moveto |
|
25 | +0 200 lineto |
|
26 | +200 200 lineto |
|
27 | +200 0 lineto |
|
28 | +0 0.2 0 0 setcmykcolor |
|
29 | +fill |
|
30 | + |
|
31 | +% Font |
|
32 | +/KozMinPro-Regular-UniJIS-UTF8-H findfont 18 scalefont setfont |
|
33 | +0 0 0 1 setcmykcolor |
|
34 | + |
|
35 | +% String |
|
36 | +27 90 moveto |
|
37 | +(ポストスクリプト) show |
|
38 | + |
|
39 | +showpage |
|
40 | + |
|
41 | +% EOF |
|
... | ... | \ No newline at end of file |
Perl/EPS\343\203\225\343\202\241\343\202\244\343\203\253\344\275\234\346\210\220/V\345\234\247\347\235\200\350\221\211\346\233\270\343\203\206\343\203\263\343\203\227\343\203\254\343\203\274\343\203\210.md
... | ... | @@ -0,0 +1,225 @@ |
1 | +~~#navi(Perl/EPSファイル作成)~~ |
|
2 | +[[_TOC_]] |
|
3 | +# V圧着葉書テンプレート |
|
4 | +## 概要 |
|
5 | +- V圧着葉書をデザインする際のテンプレート。 |
|
6 | +- Perl使っていない素のEPSファイルだけど、関連ってことで。 |
|
7 | + |
|
8 | +## 中面 |
|
9 | +``` |
|
10 | +%!PS-Adobe-3.0 EPSF-3.0 |
|
11 | +%%BoundingBox: 0 0 841.89 595.28 |
|
12 | + |
|
13 | +% V圧着葉書テンプレート (中面) |
|
14 | + |
|
15 | +% mm -> point 換算係数 |
|
16 | +/mm2point 72 25.4 div def |
|
17 | + |
|
18 | +/width 297 mm2point mul def |
|
19 | +/height 210 mm2point mul def |
|
20 | + |
|
21 | +/x0 297 mm2point mul def |
|
22 | +/y0 210 mm2point mul def |
|
23 | + |
|
24 | +/x1 27 mm2point mul def |
|
25 | +/x2 47 mm2point mul def |
|
26 | +/x3 50 mm2point mul def |
|
27 | +/x4 56 mm2point mul def |
|
28 | +/x5 150 mm2point mul def |
|
29 | +/x6 245 mm2point mul def |
|
30 | +/x7 248 mm2point mul def |
|
31 | +/x8 268 mm2point mul def |
|
32 | + |
|
33 | +/y1 7 mm2point mul neg y0 add def |
|
34 | +/y2 27 mm2point mul neg y0 add def |
|
35 | +/y3 30 mm2point mul neg y0 add def |
|
36 | +/y4 175 mm2point mul neg y0 add def |
|
37 | +/y5 178 mm2point mul neg y0 add def |
|
38 | +/y6 198 mm2point mul neg y0 add def |
|
39 | + |
|
40 | +/tx 55 mm2point mul def |
|
41 | +/ty 20 mm2point mul neg y0 add def |
|
42 | + |
|
43 | +0.3 setlinewidth |
|
44 | + |
|
45 | +% 全体枠 |
|
46 | +0 0 moveto |
|
47 | +0 height lineto |
|
48 | +width height lineto |
|
49 | +width 0 lineto |
|
50 | +closepath |
|
51 | +0 0 0 1 setcmykcolor |
|
52 | +stroke |
|
53 | + |
|
54 | +%タイトル |
|
55 | +/KozGoPro-Medium-UniJIS-UTF8-H findfont 14 scalefont setfont |
|
56 | +tx ty moveto |
|
57 | +0 0 0 1 setcmykcolor |
|
58 | +(V圧着葉書テンプレート (中面)) show |
|
59 | + |
|
60 | +% 断ち落とし込みの領域 |
|
61 | +x2 y2 moveto x7 y2 lineto x7 y5 lineto x2 y5 lineto |
|
62 | +closepath |
|
63 | +1 0 0 0 setcmykcolor |
|
64 | +stroke |
|
65 | + |
|
66 | +% 断裁後の領域 |
|
67 | +x3 y3 moveto x6 y3 lineto x6 y4 lineto x3 y4 lineto |
|
68 | +closepath |
|
69 | +1 0 0 0 setcmykcolor |
|
70 | +stroke |
|
71 | + |
|
72 | +% トンボ |
|
73 | +x2 y1 moveto x2 y3 lineto x1 y3 lineto |
|
74 | +x3 y1 moveto x3 y2 lineto x1 y2 lineto |
|
75 | +x6 y1 moveto x6 y2 lineto x8 y2 lineto |
|
76 | +x7 y1 moveto x7 y3 lineto x8 y3 lineto |
|
77 | +x1 y4 moveto x2 y4 lineto x2 y6 lineto |
|
78 | +x1 y5 moveto x3 y5 lineto x3 y6 lineto |
|
79 | +x6 y6 moveto x6 y5 lineto x8 y5 lineto |
|
80 | +x7 y6 moveto x7 y4 lineto x8 y4 lineto |
|
81 | +x5 y1 moveto x5 y2 lineto |
|
82 | +x5 y5 moveto x5 y6 lineto |
|
83 | +0 0 0 1 setcmykcolor |
|
84 | +stroke |
|
85 | + |
|
86 | +% 剥がししろ |
|
87 | +x2 y2 moveto x4 y2 lineto x4 y5 lineto x2 y5 lineto |
|
88 | +1 0.8 0 0 setcmykcolor |
|
89 | +fill |
|
90 | + |
|
91 | +showpage |
|
92 | + |
|
93 | +% EOF |
|
94 | +``` |
|
95 | + |
|
96 | +## 宛名面 |
|
97 | +``` |
|
98 | +%!PS-Adobe-3.0 EPSF-3.0 |
|
99 | +%%BoundingBox: 0 0 841.89 595.28 |
|
100 | + |
|
101 | +% V圧着葉書テンプレート (宛名面) |
|
102 | + |
|
103 | +% mm -> point 換算係数 |
|
104 | +/mm2point 72 25.4 div def |
|
105 | + |
|
106 | +/width 297 mm2point mul def |
|
107 | +/height 210 mm2point mul def |
|
108 | + |
|
109 | +/x0 297 mm2point mul def |
|
110 | +/y0 210 mm2point mul def |
|
111 | + |
|
112 | +/x1 27 mm2point mul neg x0 add def |
|
113 | +/x2 47 mm2point mul neg x0 add def |
|
114 | +/x3 50 mm2point mul neg x0 add def |
|
115 | +/x4 150 mm2point mul neg x0 add def |
|
116 | +/x5 245 mm2point mul neg x0 add def |
|
117 | +/x6 248 mm2point mul neg x0 add def |
|
118 | +/x7 268 mm2point mul neg x0 add def |
|
119 | + |
|
120 | +/y1 7 mm2point mul neg y0 add def |
|
121 | +/y2 27 mm2point mul neg y0 add def |
|
122 | +/y3 30 mm2point mul neg y0 add def |
|
123 | +/y4 175 mm2point mul neg y0 add def |
|
124 | +/y5 178 mm2point mul neg y0 add def |
|
125 | +/y6 198 mm2point mul neg y0 add def |
|
126 | + |
|
127 | +/tx 55 mm2point mul def |
|
128 | +/ty 20 mm2point mul neg y0 add def |
|
129 | + |
|
130 | +/bx1 48.1 8 add mm2point mul neg x4 add def |
|
131 | +/bx2 7.0 mm2point mul bx1 add def |
|
132 | +/bx3 14.0 mm2point mul bx1 add def |
|
133 | +/bx4 21.7 mm2point mul bx1 add def |
|
134 | +/bx5 28.5 mm2point mul bx1 add def |
|
135 | +/bx6 35.3 mm2point mul bx1 add def |
|
136 | +/bx7 42.1 mm2point mul bx1 add def |
|
137 | +/bx8 20.2 mm2point mul bx1 add def |
|
138 | +/by1 11.8 mm2point mul neg y3 add def |
|
139 | +/by2 15.8 mm2point mul neg y3 add def |
|
140 | + |
|
141 | +/bw 6.1 mm2point mul def |
|
142 | +/bh 8.4 mm2point mul neg def |
|
143 | + |
|
144 | +/drawBox { |
|
145 | + 2 dict begin |
|
146 | + /yy exch def |
|
147 | + /xx exch def |
|
148 | + xx yy moveto |
|
149 | + bw 0 rlineto |
|
150 | + 0 bh rlineto |
|
151 | + bw neg 0 rlineto |
|
152 | + closepath |
|
153 | + stroke |
|
154 | + end |
|
155 | +} def |
|
156 | + |
|
157 | +0.3 setlinewidth |
|
158 | + |
|
159 | +% 全体枠 |
|
160 | +0 0 moveto |
|
161 | +0 height lineto |
|
162 | +width height lineto |
|
163 | +width 0 lineto |
|
164 | +closepath |
|
165 | +0 0 0 1 setcmykcolor |
|
166 | +stroke |
|
167 | + |
|
168 | +%タイトル |
|
169 | +/KozGoPro-Medium-UniJIS-UTF8-H findfont 14 scalefont setfont |
|
170 | +tx ty moveto |
|
171 | +0 0 0 1 setcmykcolor |
|
172 | +(V圧着葉書テンプレート (宛名面)) show |
|
173 | + |
|
174 | +% 断ち落とし込みの領域 |
|
175 | +x2 y2 moveto x6 y2 lineto x6 y5 lineto x2 y5 lineto |
|
176 | +closepath |
|
177 | +1 0 0 0 setcmykcolor |
|
178 | +stroke |
|
179 | + |
|
180 | +% 断裁後の領域 |
|
181 | +x3 y3 moveto x5 y3 lineto x5 y4 lineto x3 y4 lineto |
|
182 | +closepath |
|
183 | +1 0 0 0 setcmykcolor |
|
184 | +stroke |
|
185 | + |
|
186 | +% トンボ |
|
187 | +x2 y1 moveto x2 y3 lineto x1 y3 lineto |
|
188 | +x3 y1 moveto x3 y2 lineto x1 y2 lineto |
|
189 | +x5 y1 moveto x5 y2 lineto x7 y2 lineto |
|
190 | +x6 y1 moveto x6 y3 lineto x7 y3 lineto |
|
191 | +x1 y4 moveto x2 y4 lineto x2 y6 lineto |
|
192 | +x1 y5 moveto x3 y5 lineto x3 y6 lineto |
|
193 | +x5 y6 moveto x5 y5 lineto x7 y5 lineto |
|
194 | +x6 y6 moveto x6 y4 lineto x7 y4 lineto |
|
195 | +x4 y1 moveto x4 y2 lineto |
|
196 | +x4 y5 moveto x4 y6 lineto |
|
197 | +0 0 0 1 setcmykcolor |
|
198 | +stroke |
|
199 | + |
|
200 | +% 郵便番号枠 |
|
201 | +0 1 1 0 setcmykcolor |
|
202 | + |
|
203 | +0.5 mm2point mul setlinewidth |
|
204 | +bx1 by1 drawBox |
|
205 | +bx2 by1 drawBox |
|
206 | +bx3 by1 drawBox |
|
207 | +0.3 mm2point mul setlinewidth |
|
208 | +bx4 by1 drawBox |
|
209 | +bx5 by1 drawBox |
|
210 | +bx6 by1 drawBox |
|
211 | +bx7 by1 drawBox |
|
212 | +0.5 mm2point mul setlinewidth |
|
213 | +bx8 by2 moveto bx4 by2 lineto |
|
214 | +stroke |
|
215 | + |
|
216 | +showpage |
|
217 | + |
|
218 | +% EOF |
|
219 | +``` |
|
220 | + |
|
221 | +## ダウンロード |
|
222 | +- EPSファイルとそれをAcrobat Distiller 6でPDFに変換したもの<br /> |
|
223 | +[VAH.zip](VAH.zip) |
|
224 | + |
|
225 | +~~#navi(Perl/EPSファイル作成)~~ |
|
... | ... | \ No newline at end of file |
Perl/EPS\343\203\225\343\202\241\343\202\244\343\203\253\344\275\234\346\210\220/\343\202\250\343\203\263\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260.md
... | ... | @@ -0,0 +1,144 @@ |
1 | +~~#navi(Perl/EPSファイル作成)~~ |
|
2 | +[[_TOC_]] |
|
3 | +# エンコーディングと文字列の原点 |
|
4 | +## 概要 |
|
5 | +- 使用しているフォントは「小塚ゴシック Pro - M」。 |
|
6 | +- EPS中で「Unicode(UTF8)」で指定する場合は「KozGoPro-Medium-UniJIS-UTF8-H」と記述する。(横書き) |
|
7 | +- EPS中で「Unicode(UCS2)」で指定する場合は「KozGoPro-Medium-UniJIS-UCS2-H」と記述する。(横書き) |
|
8 | +- EPS中で「Unicode(UTF8)」で指定する場合は「KozGoPro-Medium-UniJIS-UTF8-V」と記述する。(縦書き) |
|
9 | +- EPS中で「Unicode(UCS2)」で指定する場合は「KozGoPro-Medium-UniJIS-UCS2-V」と記述する。(縦書き) |
|
10 | + |
|
11 | +## ソースコード |
|
12 | +``` |
|
13 | +# EPS作成 |
|
14 | +# テキストの配置 |
|
15 | +# このソースは UTF8N, LF で保存すること |
|
16 | + |
|
17 | +use strict; |
|
18 | +use utf8; |
|
19 | +use Encode qw/encode decode/; |
|
20 | + |
|
21 | +my $eps_file = 'GA2.eps'; |
|
22 | +my $mm2point = 72 / 25.4; |
|
23 | + |
|
24 | +# A4サイズ |
|
25 | +my $width = sprintf( "%.2f", 210 * $mm2point ); |
|
26 | +my $height = sprintf( "%.2f", 297 * $mm2point ); |
|
27 | + |
|
28 | +my $String = "ギャラクシーエンジェる〜ん Oct 2006"; |
|
29 | +my $String_ucs2 = &str_to_ucs2( $String ); |
|
30 | +my $String_utf8 = &str_to_utf8( $String ); |
|
31 | +my $StringFontSize = 24; |
|
32 | + |
|
33 | +my $x1 = 4 * $StringFontSize; |
|
34 | +my $y1 = $height - 4 * $StringFontSize; |
|
35 | + |
|
36 | +my $x2 = $x1; |
|
37 | +my $y2 = $height - 6 * $StringFontSize; |
|
38 | + |
|
39 | +my $x3 = $x1; |
|
40 | +my $y3 = $height - 8 * $StringFontSize; |
|
41 | + |
|
42 | +my $x4 = 9 * $StringFontSize; |
|
43 | +my $y4 = $height - 11 * $StringFontSize; |
|
44 | + |
|
45 | +my $x5 = 13 * $StringFontSize; |
|
46 | +my $y5 = $y4; |
|
47 | + |
|
48 | +my $x6 = 17 * $StringFontSize; |
|
49 | +my $y6 = $y4; |
|
50 | + |
|
51 | +my $eps = ''; |
|
52 | + |
|
53 | +$eps .=<<EOL; |
|
54 | +%!PS-Adobe-3.0 EPSF-3.0 |
|
55 | +%%BoundingBox: 0 0 $width $height |
|
56 | + |
|
57 | +/putText { |
|
58 | + 4 dict begin |
|
59 | + /str exch def |
|
60 | + /encode exch def |
|
61 | + /ty exch def |
|
62 | + /tx exch def |
|
63 | + 0 1 1 0 setcmykcolor |
|
64 | + tx ty moveto |
|
65 | + tx ty 2 0 360 arc |
|
66 | + fill |
|
67 | + 0 0 0 1 setcmykcolor |
|
68 | + encode findfont $StringFontSize scalefont setfont |
|
69 | + tx ty moveto |
|
70 | + str show |
|
71 | + end |
|
72 | +} def |
|
73 | + |
|
74 | +% 全体枠 |
|
75 | +0 0 moveto |
|
76 | +0 $height lineto |
|
77 | +$width $height lineto |
|
78 | +$width 0 lineto |
|
79 | +closepath |
|
80 | +1 setlinewidth |
|
81 | +0 0 0 1 setcmykcolor |
|
82 | +stroke |
|
83 | + |
|
84 | +% 小塚ゴシック Pro - M |
|
85 | +$x1 $y1 /KozGoPro-Medium-UniJIS-UTF8-H <$String_utf8> putText |
|
86 | +$x2 $y2 /KozGoPro-Medium-UniJIS-UCS2-H <$String_ucs2> putText |
|
87 | +$x3 $y3 /KozGoPro-Medium-UniJIS-UCS2-HW-H <$String_ucs2> putText |
|
88 | +$x4 $y4 /KozGoPro-Medium-UniJIS-UTF8-V <$String_utf8> putText |
|
89 | +$x5 $y5 /KozGoPro-Medium-UniJIS-UCS2-V <$String_ucs2> putText |
|
90 | +$x6 $y6 /KozGoPro-Medium-UniJIS-UCS2-HW-V <$String_ucs2> putText |
|
91 | + |
|
92 | +showpage |
|
93 | +EOL |
|
94 | + |
|
95 | +open( OUT, ">:encoding(utf8)", $eps_file ) || die( "can't open '" . $eps_file . "'.\n" ); |
|
96 | +print OUT $eps; |
|
97 | +close( OUT ); |
|
98 | + |
|
99 | +exit(); |
|
100 | + |
|
101 | +#### Subroutine #### |
|
102 | + |
|
103 | +sub str_to_ucs2 |
|
104 | +{ |
|
105 | + my( $sIn ) = @_; |
|
106 | + my( $sOut, $len, $i ); |
|
107 | + |
|
108 | + $sOut = ''; |
|
109 | + |
|
110 | + $len = length( $sIn ); |
|
111 | + for( $i=0; $i<$len; ++$i ){ |
|
112 | + $sOut .= sprintf( "%04x ", unpack( "U", substr( $sIn, $i, 1 ))); |
|
113 | + } |
|
114 | + chop( $sOut ); |
|
115 | + |
|
116 | + return $sOut; |
|
117 | +} |
|
118 | + |
|
119 | +sub str_to_utf8 |
|
120 | +{ |
|
121 | + my( $sIn ) = @_; |
|
122 | + my( $sOut, $len, $i ); |
|
123 | + |
|
124 | + $sOut = ''; |
|
125 | + |
|
126 | + $len = length( $sIn ); |
|
127 | + for( $i=0; $i<$len; ++$i ){ |
|
128 | + $sOut .= unpack( "H8", substr( $sIn, $i, 1 ) ) . ' '; |
|
129 | + } |
|
130 | + chop( $sOut ); |
|
131 | + |
|
132 | + return $sOut; |
|
133 | +} |
|
134 | + |
|
135 | +# EOF |
|
136 | +``` |
|
137 | + |
|
138 | +## ダウンロード |
|
139 | +- ソースコードと出力されるEPSファイル<br /> |
|
140 | +[GA2.zip](GA2.zip) |
|
141 | +- EPSファイルをAcrobat Distiller 6でPDFに変換したもの<br /> |
|
142 | +[GA2.pdf](GA2.pdf) |
|
143 | + |
|
144 | +~~#navi(Perl/EPSファイル作成)~~ |
|
... | ... | \ No newline at end of file |
Perl/EPS\343\203\225\343\202\241\343\202\244\343\203\253\344\275\234\346\210\220/\346\226\207\345\255\227\343\201\256\345\233\236\350\273\242.md
... | ... | @@ -0,0 +1,111 @@ |
1 | +~~#navi(Perl/EPSファイル作成)~~ |
|
2 | +[[_TOC_]] |
|
3 | +# 文字の回転 |
|
4 | +## 概要 |
|
5 | +- 使用しているフォントは「小塚明朝 Std - M」。 |
|
6 | +- EPS中で「Unicode(UCS2)」で指定する場合は「KozMinStd-Medium-UniJIS-UCS2-V」と記述する。(縦書き) |
|
7 | +- EPS中で「Shift_JIS」で指定する場合は「KozMinStd-Medium-90ms-RKSJ-V」と記述する。(縦書き) |
|
8 | + |
|
9 | +## ソースコード |
|
10 | +``` |
|
11 | +# EPS作成 |
|
12 | +# テキストの配置 |
|
13 | +# このソースは UTF8N, LF で保存すること |
|
14 | + |
|
15 | +use strict; |
|
16 | +use utf8; |
|
17 | +use Encode qw/encode decode/; |
|
18 | + |
|
19 | +my $eps_file = 'Jugemu_u.eps'; |
|
20 | +my $mm2point = 72 / 25.4; |
|
21 | + |
|
22 | +# A4サイズ |
|
23 | +my $width = sprintf( "%.2f", 210 * $mm2point ); |
|
24 | +my $height = sprintf( "%.2f", 297 * $mm2point ); |
|
25 | + |
|
26 | +my $x0 = sprintf( "%.2f", $width / 2 ); |
|
27 | +my $y0 = sprintf( "%.2f", $height / 2 ); |
|
28 | + |
|
29 | +my $String = "寿限無 寿限無 五劫の擦り切れ 海砂利水魚の 水行末 雲来末 風来末 " |
|
30 | + . "食う寝る処に住む処 やぶら小路の藪柑子 パイポパイポ パイポのシューリンガン " |
|
31 | + . "シューリンガンのグーリンダイ グーリンダイのポンポコピーのポンポコナーの 長久命の長助"; |
|
32 | +my $StringFontSize = 32; |
|
33 | + |
|
34 | +my $Pi = 3.141592; |
|
35 | + |
|
36 | +my ( $len, $x, $y, $r, $theta, $i ); |
|
37 | + |
|
38 | +my $eps = ''; |
|
39 | + |
|
40 | +$eps .=<<EOL; |
|
41 | +%!PS-Adobe-3.0 EPSF-3.0 |
|
42 | +%%BoundingBox: 0 0 $width $height |
|
43 | + |
|
44 | +/putText { |
|
45 | + 4 dict begin |
|
46 | + /char exch def |
|
47 | + /angle exch def |
|
48 | + /ty exch def |
|
49 | + /tx exch def |
|
50 | + gsave |
|
51 | + tx ty translate |
|
52 | + angle rotate |
|
53 | + 0 0 moveto |
|
54 | + char show |
|
55 | + grestore |
|
56 | + end |
|
57 | +} def |
|
58 | + |
|
59 | +% 全体枠 |
|
60 | +0 0 moveto |
|
61 | +0 $height lineto |
|
62 | +$width $height lineto |
|
63 | +$width 0 lineto |
|
64 | +closepath |
|
65 | +1 setlinewidth |
|
66 | +0 0 0 1 setcmykcolor |
|
67 | +stroke |
|
68 | + |
|
69 | +% 小塚明朝 Std - M (縦書き) |
|
70 | +/KozMinStd-Medium-UniJIS-UCS2-V findfont $StringFontSize scalefont setfont |
|
71 | +0 0 0 1 setcmykcolor |
|
72 | + |
|
73 | +EOL |
|
74 | + |
|
75 | +$len = length( $String ); |
|
76 | +$r = $StringFontSize * 8; |
|
77 | +$theta = 0; |
|
78 | + |
|
79 | +for( $i=0; $i<$len; ++ $i ){ |
|
80 | + $x = $x0 + $r * cos( $theta ); |
|
81 | + $y = $y0 + $r * sin( $theta ); |
|
82 | + $eps .= sprintf( "%.2f %.2f %.1f <%04x> putText\n", |
|
83 | + $x, $y, $theta*180/$Pi, unpack("U",substr($String,$i,1)) ); |
|
84 | + $theta -= $StringFontSize * 1.05 / $r; |
|
85 | + if ( $theta < -2 * $Pi ){ |
|
86 | + $theta += 2 * $Pi; |
|
87 | + } |
|
88 | + $r -= $StringFontSize * $StringFontSize * 1.4 / ( 2 * $Pi * $r ); |
|
89 | +} |
|
90 | + |
|
91 | +$eps .=<<EOL; |
|
92 | + |
|
93 | +showpage |
|
94 | +EOL |
|
95 | + |
|
96 | +open( OUT, ">:encoding(utf8)", $eps_file ) || die( "can't open '" . $eps_file . "'.\n" ); |
|
97 | +print OUT $eps; |
|
98 | +close( OUT ); |
|
99 | + |
|
100 | +exit(); |
|
101 | + |
|
102 | +# EOF |
|
103 | +``` |
|
104 | + |
|
105 | +## ダウンロード |
|
106 | +- ソースコード(UCS2版, Shift_JIS版)と出力されるEPSファイル(UCS2版, Shift_JIS版)<br /> |
|
107 | +[Jugemu.zip](Jugemu.zip) |
|
108 | +- EPSファイルをAcrobat Distiller 6でPDFに変換したもの<br /> |
|
109 | +[Jugemu.pdf](Jugemu.pdf) |
|
110 | + |
|
111 | +~~#navi(Perl/EPSファイル作成)~~ |
|
... | ... | \ No newline at end of file |
Perl/EscapeSlash.md
... | ... | @@ -0,0 +1,124 @@ |
1 | +# C言語スタイルで文字列のエスケープ/アンエスケープを行う |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- 入力された文字列の中の改行など直接記述できない文字にバックスラッシュを付けてエスケープする。 |
|
6 | +- PHP関数 [addcslashes](http://jp2.php.net/manual/ja/%66%75%6e%63%74%69%6f%6e%2e%61%64%64%63%73%6c%61%73%68%65%73%2e%70%68%70) / [stripcslashes](http://jp2.php.net/manual/ja/%66%75%6e%63%74%69%6f%6e%2e%73%74%72%69%70%63%73%6c%61%73%68%65%73%2e%70%68%70) |
|
7 | +- 2つ目の引数にハッシュを指定することで別の変換を行うことができます。 |
|
8 | + - 書いたはいいが、2番目のパラメータをハッシュだと思い込んでたがホントは文字列だった。(--;)<br /> |
|
9 | +addcslashes, stripcslashes という関数名は付けられないなぁ。 |
|
10 | +- \xXX 形式には対応していません。 |
|
11 | + |
|
12 | +## ソースコード |
|
13 | +- [EscapeSlash.zip](EscapeSlash.zip) |
|
14 | + |
|
15 | +### EscapeSlash.pm |
|
16 | +``` |
|
17 | +# C言語スタイルで文字列のエスケープ/アンエスケープを行う |
|
18 | +# by TakeAsh |
|
19 | +# ネタ元 http://jp2.php.net/manual/ja/function.addcslashes.php |
|
20 | +# ネタ元 http://blog.livedoor.jp/dankogai/archives/50940023.html |
|
21 | +# |
|
22 | +# v0.00 2009.03.04 |
|
23 | +# v0.01 2009.03.12 空文字列が渡されたときはundefではなく空文字列を返すようにした。 |
|
24 | +# unescapeslashはescapeslashを呼ぶようにした。 |
|
25 | +# \e(0x1b)もエスケープするようにした。 |
|
26 | +# v0.02 2009.03.17 数値0が渡されたときに""ではなく0を返すようにした。 |
|
27 | +# v0.03 2009.08.14 ",'もエスケープするようにした。 |
|
28 | +# |
|
29 | +# 書いたはいいが、2番目のパラメータをハッシュだと思い込んでたがホントは文字列だった。(--;) |
|
30 | +# addcslashes, stripcslashes という関数名は付けられないなぁ。 |
|
31 | +# \xXX 形式には対応していません。 |
|
32 | + |
|
33 | +package EscapeSlash; |
|
34 | + |
|
35 | +use strict; |
|
36 | +use warnings; |
|
37 | +use utf8; |
|
38 | + |
|
39 | +use Exporter; |
|
40 | +our @ISA = qw(Exporter); |
|
41 | +our @EXPORT = qw(escapeslash unescapeslash); |
|
42 | + |
|
43 | +## スケープする文字セット |
|
44 | +my %charset_factory = ( |
|
45 | + "\\"=>"\\\\", "\n"=>"\\n", "\r"=>"\\r", "\t"=>"\\t", "\0"=>"\\0", |
|
46 | + "\a"=>"\\a", "\b"=>"\\b", "\f"=>"\\f", "\e" => "\\e", |
|
47 | + "\""=>"\\\"", "'"=>"\\'" |
|
48 | + # , "\v"=>"\\v" |
|
49 | +); |
|
50 | + |
|
51 | +## C言語スタイルで文字列のエスケープを行う |
|
52 | +# @param $str [in] 変換対象文字列 |
|
53 | +# @param %charset [in] エスケープする文字セット(オプション) |
|
54 | +# @return エスケープされた文字列 |
|
55 | +sub escapeslash{ |
|
56 | + my $str; |
|
57 | + $str = shift or return $str; # undef, "", 0 ならリターン |
|
58 | + my %charset = defined( $_[0] ) ? %{shift()} : %charset_factory ; # %{shift} だとハッシュへのリファレンスが受け取れない |
|
59 | + my $charclass = join( '|', map{ quotemeta } keys( %charset ) ); |
|
60 | + $str =~ s/($charclass)/$charset{$1}/msgex; |
|
61 | + return $str; |
|
62 | +} |
|
63 | + |
|
64 | +## C言語スタイルで文字列のアンエスケープを行う |
|
65 | +# @param $str [in] 変換対象文字列 |
|
66 | +# @param %charset [in] アンエスケープする文字セット(オプション) |
|
67 | +# @return アンエスケープされた文字列 |
|
68 | +sub unescapeslash{ |
|
69 | + my $str = shift; |
|
70 | + my %charset = defined( $_[0] ) ? %{shift()} : %charset_factory ; # %{shift} だとハッシュへのリファレンスが受け取れない |
|
71 | + %charset = reverse( %charset ); |
|
72 | + return escapeslash( $str, \%charset ); |
|
73 | +} |
|
74 | + |
|
75 | +1; |
|
76 | + |
|
77 | +# EOF |
|
78 | +``` |
|
79 | + |
|
80 | +### TestEscapeSlash.pl |
|
81 | +``` |
|
82 | +# EscapeSlash.pm の動作テスト |
|
83 | + |
|
84 | +use strict; |
|
85 | +use warnings; |
|
86 | +use utf8; |
|
87 | +use Data::Dump qw(dump); |
|
88 | + |
|
89 | +use EscapeSlash; |
|
90 | + |
|
91 | +my @Sample = ( |
|
92 | + "ab\\cd", "ab\ncd", "ab\rcd", "ab\tcd", "ab\0cd", "ab\"cd", "ab'cd", "ab?cd", "ab&cd", |
|
93 | + "ab\\\\cd", "ab\\ncd", "ab\\rcd", "ab\\tcd", "ab\\0cd", "ab\\\"cd", "ab\\'cd", "ab\\?cd", "ab\\&cd", |
|
94 | + "", undef, 0, "0", |
|
95 | +); |
|
96 | + |
|
97 | +my %ConvSet = ( "\\" => "\\\\", "?" => "\\?", "&"=>"\\&" ); |
|
98 | + |
|
99 | +my @TestData = ( @ARGV > 0 ) ? @ARGV : @Sample ; |
|
100 | + |
|
101 | +print "ConvSet for esc2,unesc2\n" . dump(%ConvSet)."\n\n"; |
|
102 | + |
|
103 | +foreach my $test ( @TestData ){ |
|
104 | + printf( "org:\t%s\n", dump($test) ); |
|
105 | + printf( "esc:\t%s\n", dump(escapeslash($test)) ); |
|
106 | + printf( "unesc:\t%s\n", dump(unescapeslash($test)) ); |
|
107 | + printf( "esc2:\t%s\n", dump(escapeslash($test,\%ConvSet)) ); |
|
108 | + printf( "unesc2:\t%s\n", dump(unescapeslash($test,\%ConvSet)) ); |
|
109 | + #printf( "Reverse:\t%d\n", $test eq unescapeslash(escapeslash($test)) ); |
|
110 | + print "\n"; |
|
111 | +} |
|
112 | + |
|
113 | +# EOF |
|
114 | +``` |
|
115 | + |
|
116 | +## Link |
|
117 | +- [[Microsoft SQL Server インポート/エクスポート|Perl/MSSQL_ImpExp]] |
|
118 | + |
|
119 | +- [勝手に添削 - 40行で作るPerl用テンプレートエンジン](http://blog.livedoor.jp/dankogai/archives/50940023.html) |
|
120 | +- [javascript - String.prototype.quotemeta() があればいいんじゃね?](http://blog.livedoor.jp/dankogai/archives/51058313.html) |
|
121 | +- [Perlメモ](http://www.din.or.jp/~ohzaki/perl.htm) / [改行コードを統一する](http://www.din.or.jp/~ohzaki/perl.htm#CRLF_Unify) |
|
122 | + |
|
123 | +- [perldoc.jp](http://perldoc.jp/) / [Perlのリファレンスとネストしたデータ構造](http://perldoc.jp/pod/perlref) / [あまりシンボリックではないリファレンス](http://perldoc.jp/pod/perlref#Not-so-symbolic32references) |
|
124 | + - perl のバージョン 5.001 で、中かっこに囲まれたシンボリックリファレンスが よりクォートのように、ちょうどそれが文字列の中にあるかのように 振る舞うという新たな機能が読みやすさのために追加されました。 |
|
... | ... | \ No newline at end of file |
Perl/GD.md
... | ... | @@ -0,0 +1,64 @@ |
1 | +# GDライブラリを使って画像の縮小版を作成する |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +GDライブラリを使って画像の 1/2, 1/3, 1/4 縮小版を一括で作成する。 |
|
6 | + |
|
7 | +## スクリプト |
|
8 | +- [shrink.zip](shrink.zip) |
|
9 | + |
|
10 | +## shrink.pl |
|
11 | +``` |
|
12 | +# 画像一括縮小 |
|
13 | +# 「PDATA」以下のpngファイルを1/2,1/3,1/4に縮小し「PDATA2」「PDATA3」「PDATA4」へ保存する。 |
|
14 | + |
|
15 | +use strict; |
|
16 | +use warnings; |
|
17 | +use utf8; |
|
18 | +use GD; |
|
19 | + |
|
20 | +my @filelist = <./PDATA/*.png>; |
|
21 | +# print join( "\n", @filelist ); |
|
22 | + |
|
23 | +my $filein; # 入力ファイル名 |
|
24 | +my $imgsrc; # 入力画像 |
|
25 | +my( $width, $height ); # 入力画像の幅と高さ |
|
26 | +my $num; # 画像ファイル数 |
|
27 | +my $cnt = 0; # カウンタ |
|
28 | + |
|
29 | +$num = scalar( @filelist ); |
|
30 | +$| = 1; |
|
31 | +foreach $filein ( @filelist ){ |
|
32 | + $imgsrc = GD::Image->new( $filein ) || die( $! ); |
|
33 | + ( $width, $height ) = $imgsrc->getBounds(); |
|
34 | + shrink( $filein, 2 ); |
|
35 | + shrink( $filein, 3 ); |
|
36 | + shrink( $filein, 4 ); |
|
37 | + printf STDERR ( "%d/%d\r", ++$cnt, $num ); |
|
38 | +} |
|
39 | +$| = 0; |
|
40 | + |
|
41 | +sub shrink |
|
42 | +{ |
|
43 | + my( $filein, $div ) = @_; |
|
44 | + my $fhout; # 出力ファイルハンドル |
|
45 | + my $imgdst; # 出力画像 |
|
46 | + my( $w2, $h2 ); # 出力画像の幅と高さ |
|
47 | + my $fileout; # 出力ファイル名 |
|
48 | + |
|
49 | + $w2 = int( $width / $div ); # intが無いとクラッシュする |
|
50 | + $h2 = int( $height / $div ); # intが無いとクラッシュする |
|
51 | + $imgdst = new GD::Image( $w2, $h2, 0 ); |
|
52 | + $imgdst->copyResized( $imgsrc, 0, 0, 0, 0, $w2, $h2, $width, $height ); |
|
53 | + $fileout = $filein; |
|
54 | + $fileout =~ s#/PDATA/#/PDATA${div}/#; |
|
55 | + open( $fhout, ">:bytes", $fileout ) || die( $! ); |
|
56 | + binmode( $fhout ); # ">:bytes" があればいらないはずだが、無いと読めないファイルが出来る。 |
|
57 | + print $fhout $imgdst->png; |
|
58 | + close( $fhout ); |
|
59 | +} |
|
60 | + |
|
61 | +# EOF |
|
62 | +``` |
|
63 | + |
|
64 | +## リンク |
|
... | ... | \ No newline at end of file |
Perl/GMTtoLocalTime.md
... | ... | @@ -0,0 +1,96 @@ |
1 | +# GMT からローカルタイム(JST)に変換 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- GMT を [CPAN:HTTP-Date](http://search.cpan.org/dist/HTTP-Date) および Perl 標準機能のみを使ってローカルタイムに変換する。 |
|
6 | +- GMTtoLocal2 は時差の指定は無視する。 |
|
7 | + |
|
8 | +## ソース |
|
9 | +- [GMTtoLocal.zip](GMTtoLocal.zip) |
|
10 | +```perl |
|
11 | +#!/usr/bin/perl |
|
12 | +# GMT からローカルタイム(JST)に変換 |
|
13 | + |
|
14 | +use strict; |
|
15 | +use warnings; |
|
16 | +use utf8; |
|
17 | +use Encode; |
|
18 | +use HTTP::Date qw( time2str str2time time2iso ); |
|
19 | +use POSIX qw(strftime); |
|
20 | +use Time::Local; |
|
21 | + |
|
22 | +my $charsetConsole = 'CP932'; |
|
23 | +my $charsetFile = 'UTF-8'; |
|
24 | + |
|
25 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
26 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
27 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
28 | + |
|
29 | +my @sample = ( |
|
30 | + '2011-11-23T00:00:00Z', |
|
31 | + '2011-12-31T20:00:00Z', |
|
32 | + '2012-02-28T21:00:00+00:00', |
|
33 | + '2012-02-28T21:00:00+09:00', |
|
34 | +); |
|
35 | + |
|
36 | +foreach my $src ( @sample ){ |
|
37 | + printf( "Source\t\t%s\nHTTP::Date\t%s\nStandard\t%s\n\n", |
|
38 | + $src, GMTtoLocal1( $src ), GMTtoLocal2( $src ) ); |
|
39 | +} |
|
40 | + |
|
41 | +exit(); |
|
42 | + |
|
43 | +# HTTP::Date を使用 |
|
44 | +# http://search.cpan.org/dist/HTTP-Date/ |
|
45 | +sub GMTtoLocal1 |
|
46 | +{ |
|
47 | + my( $gmt ) = @_; |
|
48 | + return time2iso( str2time( $gmt, 'Asia/Tokyo' ) ); |
|
49 | +} |
|
50 | + |
|
51 | +# Perl標準機能のみ |
|
52 | +# http://chalow.net/2010-03-01-5.html |
|
53 | +# 時差の指定は無視して常にGMTと見なす。 |
|
54 | +sub GMTtoLocal2 |
|
55 | +{ |
|
56 | + my( $gmt ) = @_; |
|
57 | + my $ret = $gmt; |
|
58 | + if ( $gmt =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/ ){ |
|
59 | + my $utm = timegm( $6, $5, $4, $3, $2-1, $1 ); |
|
60 | + $ret = strftime( "%Y-%m-%d %H:%M:%S", localtime( $utm ) ); |
|
61 | + } |
|
62 | + return $ret; |
|
63 | +} |
|
64 | + |
|
65 | +# EOF |
|
66 | +``` |
|
67 | + |
|
68 | +## 出力 |
|
69 | +``` |
|
70 | +Source 2011-11-23T00:00:00Z |
|
71 | +HTTP::Date 2011-11-23 09:00:00 |
|
72 | +Standard 2011-11-23 09:00:00 |
|
73 | + |
|
74 | +Source 2011-12-31T20:00:00Z |
|
75 | +HTTP::Date 2012-01-01 05:00:00 |
|
76 | +Standard 2012-01-01 05:00:00 |
|
77 | + |
|
78 | +Source 2012-02-28T21:00:00+00:00 |
|
79 | +HTTP::Date 2012-02-29 06:00:00 |
|
80 | +Standard 2012-02-29 06:00:00 |
|
81 | + |
|
82 | +Source 2012-02-28T21:00:00+09:00 |
|
83 | +HTTP::Date 2012-02-28 21:00:00 |
|
84 | +Standard 2012-02-29 06:00:00 |
|
85 | +``` |
|
86 | + |
|
87 | +## リンク |
|
88 | +- [CPAN:HTTP-Date](http://search.cpan.org/dist/HTTP-Date) |
|
89 | +- [CPAN:Time-Local](http://search.cpan.org/dist/Time-Local) |
|
90 | +- [CPAN:Time-Piece](http://search.cpan.org/dist/Time-Piece) |
|
91 | + |
|
92 | +- [たつをの ChangeLog](http://chalow.net/) |
|
93 | + - [GMT による時間表現文字列を JST に変換する Perl コード片](http://chalow.net/2010-03-01-5.html) |
|
94 | + |
|
95 | +- [サンプルコードによるPerl入門](http://d.hatena.ne.jp/perlcodesample/) |
|
96 | + - [今月の最初の日を表すTime::Pieceオブジェクトを取得する / Time::Piece Tips](http://d.hatena.ne.jp/perlcodesample/20120911/1347331536) |
|
... | ... | \ No newline at end of file |
Perl/GoogleMapAPI.md
... | ... | @@ -0,0 +1,115 @@ |
1 | +# Google Map API を使って始点終点の経路情報と地図画像を得る |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- [Google Directions API](http://code.google.com/intl/ja/apis/maps/documentation/directions/)を使って経路情報を得る。 |
|
6 | +- [Static Maps API](http://code.google.com/intl/ja/apis/maps/documentation/staticmaps/)を使って経路情報付き画像を得る。 |
|
7 | +- 事前にカレントディレクトリに保存用ディレクトリ「map」を作成しておく必要がある。 |
|
8 | +- 使用例 |
|
9 | +``` |
|
10 | +>gmap.pl 東京 ビックサイト |
|
11 | +>gmap.pl 東京 サンフランシスコ |
|
12 | +``` |
|
13 | + |
|
14 | +## ソース |
|
15 | +- [gmap.pl](gmap.pl) |
|
16 | +``` |
|
17 | +#!/usr/bin/perl |
|
18 | +# gmap.pl |
|
19 | +# 始点終点の経路情報と地図画像を得る。 |
|
20 | +# 使用法: gmap.pl <始点> <終点> |
|
21 | + |
|
22 | +use strict; |
|
23 | +use warnings; |
|
24 | +use utf8; |
|
25 | +use Encode; |
|
26 | +use LWP::UserAgent; |
|
27 | +use HTTP::Request; |
|
28 | +use JSON; |
|
29 | +use YAML::Syck; |
|
30 | + |
|
31 | +my $GoogleMapDirectionsAPI = 'http://maps.google.com/maps/api/directions/json?mode=walking&language=ja&sensor=false'; |
|
32 | +my $GoogleMapStaticAPI = 'http://maps.google.com/maps/api/staticmap?size=640x640&language=ja&sensor=false'; |
|
33 | +my $MapPath = './map/'; |
|
34 | + |
|
35 | +$YAML::Syck::ImplicitUnicode = 1; |
|
36 | + |
|
37 | +binmode( STDIN, ":encoding(CP932)" ); |
|
38 | +binmode( STDOUT, ":encoding(CP932)" ); |
|
39 | +binmode( STDERR, ":encoding(CP932)" ); |
|
40 | + |
|
41 | +my $usStart = decode( 'CP932', shift ); # unicode string |
|
42 | +my $usGoal = decode( 'CP932', shift ); # unicode string |
|
43 | +if ( !defined( $usStart ) || $usStart eq "" || !defined( $usGoal ) || $usGoal eq "" ){ |
|
44 | + die( "使用法: $0 <始点> <終点>\n" ); |
|
45 | +} |
|
46 | + |
|
47 | +my $esStart = encodeURIComponent( $usStart ); # encoded string |
|
48 | +my $esGoal = encodeURIComponent( $usGoal ); # encoded string |
|
49 | +my $usFName = $usStart . '_' . $usGoal; # unicode string |
|
50 | +my $bsFName = encode( 'CP932', $MapPath . $usFName ); # byte string |
|
51 | + |
|
52 | +#printf( "start:\t%s\t%s\ngoal:\t%s\t%s\n", $usStart, $esStart, $usGoal, $esGoal ); |
|
53 | + |
|
54 | +my $ua = LWP::UserAgent->new( keep_alive => 2 ); |
|
55 | + |
|
56 | +my $res = $ua->get( $GoogleMapDirectionsAPI . '&origin=' . $esStart . '&destination=' . $esGoal ); |
|
57 | +if ( $res->is_success ){ |
|
58 | + #print $res->content, "\n"; |
|
59 | + # http://www.donzoko.net/cgi-bin/tdiary/20100406.html#p01 |
|
60 | + my $json = JSON->new->utf8; |
|
61 | + my $usRoute = $json->decode( $res->content ); |
|
62 | + #print Dump( $usRoute ); |
|
63 | + if ( $usRoute->{'status'} eq 'OK' ){ |
|
64 | + my $usLegs = $usRoute->{'routes'}[0]{'legs'}[0]; |
|
65 | + #delete $usLegs->{'steps'}; |
|
66 | + open( my $fout, ">:utf8", $bsFName . '.yaml' ) or die( "$usFName: $!\n" ); |
|
67 | + print $fout Dump( $usLegs ); |
|
68 | + close( $fout ); |
|
69 | + |
|
70 | + my $start_lat = $usLegs->{'start_location'}{'lat'}; |
|
71 | + my $start_lng = $usLegs->{'start_location'}{'lng'}; |
|
72 | + my $end_lat = $usLegs->{'end_location'}{'lat'}; |
|
73 | + my $end_lng = $usLegs->{'end_location'}{'lng'}; |
|
74 | + my $center_lng = ( $start_lng + $end_lng ) / 2; |
|
75 | + if ( $start_lng * $end_lng < 0 && abs( $start_lng ) + abs( $end_lng ) > 180 ){ |
|
76 | + if ( $center_lng >= 0 ){ |
|
77 | + $center_lng -= 180; |
|
78 | + } else { |
|
79 | + $center_lng += 180; |
|
80 | + } |
|
81 | + } |
|
82 | + my $mapURI = $GoogleMapStaticAPI |
|
83 | + . '¢er=' . (( $start_lat + $end_lat ) / 2 ) . ',' . $center_lng |
|
84 | + . '&markers=label:S|' . $start_lat . ',' . $start_lng |
|
85 | + . '&markers=label:G|' . $end_lat . ',' . $end_lng |
|
86 | + . '&path=enc:' . $usRoute->{'routes'}[0]{'overview_polyline'}{'points'}; |
|
87 | + $ua->request( HTTP::Request->new( GET => $mapURI ), $bsFName . '.png' ); |
|
88 | + } else { |
|
89 | + die( "Error: $usRoute->{'status'}\n" ); |
|
90 | + } |
|
91 | +} else { |
|
92 | + die( "Error: $res->status_line\n" ); |
|
93 | +} |
|
94 | + |
|
95 | +sub encodeURIComponent { |
|
96 | + my $str = encode( 'utf-8', shift ); |
|
97 | + $str =~ s/([^0-9A-Za-z!'()*\-._~])/sprintf("%%%02X", ord($1))/eg; |
|
98 | + return $str; |
|
99 | +} |
|
100 | + |
|
101 | +# EOF |
|
102 | +``` |
|
103 | + |
|
104 | +## リンク |
|
105 | +- [[JavaScript/GoogleMapAPI]] |
|
106 | + |
|
107 | +- [Google Maps API ファミリー - Google Code](http://code.google.com/intl/ja/apis/maps/) |
|
108 | + - [Google Directions API](http://code.google.com/intl/ja/apis/maps/documentation/directions/) |
|
109 | + - [Static Maps API](http://code.google.com/intl/ja/apis/maps/documentation/staticmaps/) |
|
110 | + |
|
111 | +- [CPAN:JSON-XS](http://search.cpan.org/dist/JSON-XS) |
|
112 | +- [CPAN:URI](http://search.cpan.org/dist/URI) (URI::Escape) |
|
113 | + |
|
114 | +- [どんぞこCGI+--](http://www.donzoko.net/) / [どんぞこ日誌](http://www.donzoko.net/cgi-bin/tdiary/) / [JSONのドキュメントに追加した部分](http://www.donzoko.net/cgi-bin/tdiary/20100406.html#p01) |
|
115 | +- [rubyu備忘録](http://d.hatena.ne.jp/ruby-U/) / [perlとpython用encodeURIComponent()](http://d.hatena.ne.jp/ruby-U/20081110/1226313786) |
|
... | ... | \ No newline at end of file |
Perl/HTTP\343\202\242\343\202\257\343\202\273\343\202\271.md
... | ... | @@ -0,0 +1,81 @@ |
1 | +# HTTPアクセス |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 情報源 |
|
5 | + |
|
6 | +~[ActivePerl](http://www.activestate.com/ActivePerl/)には、[libwww-perl](http://lwp.linpro.no/lwp/)がパッケージとして含まれているので、ローカルの Perl/html/site/lib/lwpcook.html を参照すること。 |
|
7 | + |
|
8 | +## サンプル |
|
9 | +- [TinyProxy.zip](TinyProxy.zip) |
|
10 | +```perl |
|
11 | +#!/usr/bin/perl |
|
12 | +# TinyProxy.pl |
|
13 | +# コマンドラインで指定した URI を utf8 としてファイルに保存。 |
|
14 | + |
|
15 | +use strict; |
|
16 | +use warnings; |
|
17 | +use utf8; |
|
18 | +use Encode; |
|
19 | +use LWP::UserAgent; |
|
20 | +#use URI::Escape; |
|
21 | +use EscapeSlash; |
|
22 | + |
|
23 | +my $charsetConsole = 'CP932'; |
|
24 | +my $charsetFile = 'UTF-8'; |
|
25 | + |
|
26 | +# ファイル名/パス名として使用できない文字+α |
|
27 | +my %ConvSet = map{ $_ => '%' . uc( unpack( 'H02', $_ ) ) } split( //, '\\/*?|<>:,;% \"' ); |
|
28 | + |
|
29 | +@ARGV = map{ decode( $charsetConsole, $_ ); } @ARGV; |
|
30 | + |
|
31 | +my $url = $ARGV[0] or die( "usage: TinyProxy.pl <URI>\n" ); |
|
32 | +my $fileNameOut = $url; |
|
33 | +if ( $fileNameOut =~ m#^.*/$# ){ |
|
34 | + $fileNameOut .= 'index.html'; |
|
35 | +} |
|
36 | +$fileNameOut =~ s#^\w+://(.*)$#$1#; |
|
37 | +#$fileNameOut = uri_escape_utf8( $fileNameOut ); |
|
38 | +$fileNameOut = escapeslash( $fileNameOut, \%ConvSet ); |
|
39 | + |
|
40 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
41 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
42 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
43 | + |
|
44 | +open( my $OUT, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) ) |
|
45 | + or die( "$fileNameOut: $!\n" ); |
|
46 | +print $OUT getURI( $url ); |
|
47 | +close( $OUT ); |
|
48 | + |
|
49 | +exit(); |
|
50 | + |
|
51 | +# --- Subroutine --- |
|
52 | +sub getURI { |
|
53 | + my( $URI ) = @_; |
|
54 | + |
|
55 | + my $ua = LWP::UserAgent->new; |
|
56 | + my $req = HTTP::Request->new( GET => $URI ); |
|
57 | + |
|
58 | + # send request |
|
59 | + my $res = $ua->request( $req ); |
|
60 | + |
|
61 | + # check the outcome |
|
62 | + if ( $res->is_success ){ |
|
63 | + return $res->decoded_content; # utf8フラグ付テキスト |
|
64 | + } else { |
|
65 | + return "Error: " . $res->status_line . "\n"; |
|
66 | + } |
|
67 | +} |
|
68 | + |
|
69 | +# EOF |
|
70 | +``` |
|
71 | + |
|
72 | +## リンク |
|
73 | +- [[Perl/EscapeSlash]] |
|
74 | +- [[Perl/nicoget]] |
|
75 | + |
|
76 | +- [CPAN:libwww-perl](http://search.cpan.org/dist/libwww-perl) |
|
77 | +- [CPAN:HTTP-Message](http://search.cpan.org/dist/HTTP-Message) |
|
78 | +- [libwww-perl](http://lwp.linpro.no/lwp/) |
|
79 | +- [CPAN:URI/URI/Escape.pm](http://search.cpan.org/dist/URI/URI/Escape.pm) |
|
80 | + |
|
81 | +- [LWP::UserAgentでdecoded_contentしたら特定のContent-Typeで文字化けするのでハックした](http://blog.livedoor.jp/sasata299/archives/51212133.html) @ [(゚∀゚)o彡 sasata299's blog](http://blog.livedoor.jp/sasata299/) |
|
... | ... | \ No newline at end of file |
Perl/Home.md
... | ... | @@ -1,3 +1,32 @@ |
1 | -# Perl |
|
1 | +[[_TOC_]] |
|
2 | 2 | |
3 | -- [[Http]] |
|
3 | +# サンプルスクリプト |
|
4 | +~~#ls2()~~ |
|
5 | +- [GitHub:TakeAsh/p-usDownload](https://github.com/TakeAsh/p-usDownload) Ustream Archive Downloader |
|
6 | +- [GitHub:TakeAsh/p-RecRadiru](https://github.com/TakeAsh/p-RecRadiru) NHK Net Radio らじる★らじる を rtmpdump で録音するスクリプト |
|
7 | + |
|
8 | +# リンク |
|
9 | +- http://perldoc.jp/ |
|
10 | + - [コアドキュメント](http://perldoc.jp/index/core) |
|
11 | + - [組み込み関数](http://perldoc.jp/index/function) |
|
12 | + - [翻訳済モジュール](http://perldoc.jp/index/module) |
|
13 | + |
|
14 | +- [The CPAN Search Site](http://search.cpan.org/) |
|
15 | +- [スマートスマート](http://www.rfs.jp/) / [Perl講座](http://www.rfs.jp/sb/perl/) |
|
16 | +- [ActiveState Tool Corp.](https://www.activestate.com/) |
|
17 | + - [ActivePerl](https://www.activestate.com/activeperl/) |
|
18 | + - [ActivePerl Documentation](https://docs.activestate.com/activeperl/) |
|
19 | + - [ActivePerl 5.24 Documentation](https://docs.activestate.com/activeperl/5.24/) / [Release Notes](https://docs.activestate.com/activeperl/5.24/release.html) / [PPM, Proxies and Firewalls](https://docs.activestate.com/activeperl/5.24/faq/ActivePerl-faq2.html#ppm_and_proxies) |
|
20 | + - [ActivePerl 5.22 Documentation](https://docs.activestate.com/activeperl/5.22/) / [Release Notes](https://docs.activestate.com/activeperl/5.22/release.html) / [PPM, Proxies and Firewalls](https://docs.activestate.com/activeperl/5.22/faq/ActivePerl-faq2.html#ppm_and_proxies) |
|
21 | + - [ActivePerl 5.20 Documentation](https://docs.activestate.com/activeperl/5.20/) / [Release Notes](https://docs.activestate.com/activeperl/5.20/release.html) / [PPM, Proxies and Firewalls](https://docs.activestate.com/activeperl/5.20/faq/ActivePerl-faq2.html#ppm_and_proxies) |
|
22 | + - [ActivePerl 5.18 Documentation](https://docs.activestate.com/activeperl/5.18/) / [Release Notes](https://docs.activestate.com/activeperl/5.18/release.html) / [PPM, Proxies and Firewalls](https://docs.activestate.com/activeperl/5.18/faq/ActivePerl-faq2.html#ppm_and_proxies) |
|
23 | + - [ActivePerl 5.16 Documentation](https://docs.activestate.com/activeperl/5.16/) / [Release Notes](https://docs.activestate.com/activeperl/5.16/release.html) / [PPM, Proxies and Firewalls](https://docs.activestate.com/activeperl/5.16/faq/ActivePerl-faq2.html#ppm_and_proxies) |
|
24 | + - [ActivePerl 5.14 Documentation](https://docs.activestate.com/activeperl/5.14/) / [Release Notes](https://docs.activestate.com/activeperl/5.14/release.html) |
|
25 | + - [ActivePerl 5.12 Documentation](https://docs.activestate.com/activeperl/5.12/) / [Release Notes](https://docs.activestate.com/activeperl/5.12/release.html) |
|
26 | + - [ActivePerl 5.10 Documentation](https://docs.activestate.com/activeperl/5.10/) |
|
27 | + - [ActivePerl 5.8 Documentation](https://docs.activestate.com/activeperl/5.8/) |
|
28 | +- [Perl入門@ITpro](http://itpro.nikkeibp.co.jp/article/COLUMN/20080528/304529/) |
|
29 | +- [Perlリファレンス@ITpro](http://itpro.nikkeibp.co.jp/article/Reference/20081111/318984/) |
|
30 | + - [目的別インデックス](http://itpro.nikkeibp.co.jp/article/Reference/20080926/315520/) |
|
31 | + - [関数順インデックス](http://itpro.nikkeibp.co.jp/article/Reference/20080926/315499/) |
|
32 | +- [Perlでフォトショップ CS](http://www2.tba.t-com.ne.jp/tail/prog/perl/photoshop.html) @ [Storeroom](http://www2.tba.t-com.ne.jp/tail/) |
Perl/HostToIP.md
... | ... | @@ -0,0 +1,45 @@ |
1 | +# HostToIP |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- ホスト名からIPアドレスを求め、IPアドレスからホスト名を逆引きする。 |
|
6 | + |
|
7 | +## ソース |
|
8 | +- [HostToIP.zip](HostToIP.zip) |
|
9 | +```perl |
|
10 | +#!/usr/bin/perl |
|
11 | +# HostToIP.pl |
|
12 | +# ホスト名からIPアドレスを求める。(IPv4) |
|
13 | +# さらにIPアドレスからホスト名を逆引きする。 |
|
14 | + |
|
15 | +use strict; |
|
16 | +use warnings; |
|
17 | +use utf8; |
|
18 | +use Encode; |
|
19 | +use Socket; |
|
20 | + |
|
21 | +my $charsetConsole = 'CP932'; |
|
22 | +#my $charsetConsole = 'UTF-8'; |
|
23 | +my $charsetFile = 'UTF-8'; |
|
24 | + |
|
25 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
26 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
27 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
28 | + |
|
29 | +@ARGV = map{ decode( $charsetConsole, $_ ); } @ARGV; |
|
30 | + |
|
31 | +my $host1 = $ARGV[0] || 'localhost'; |
|
32 | +my $ipn = inet_aton( $host1 ); |
|
33 | +my $ipa = inet_ntoa( $ipn ); |
|
34 | +my $host2 = gethostbyaddr( $ipn, AF_INET ); |
|
35 | + |
|
36 | +print "$host1\n$ipa\n$host2\n"; |
|
37 | + |
|
38 | +# EOF |
|
39 | +``` |
|
40 | + |
|
41 | +## リンク |
|
42 | +- [[Perl/getHostName]] |
|
43 | + |
|
44 | +- [CPAN:Socket](http://search.cpan.org/dist/Socket) |
|
45 | +- [CPAN:Socket6](http://search.cpan.org/dist/Socket6) |
|
... | ... | \ No newline at end of file |
Perl/Http.md
... | ... | @@ -1,3 +0,0 @@ |
1 | -# HTTP |
|
2 | - |
|
3 | -- HTTP アクセス |
Perl/HttpHeader.md
... | ... | @@ -0,0 +1,45 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- 指定 URL のレスポンスの HTTP Header を表示する。 |
|
5 | + |
|
6 | +# ソース |
|
7 | +- [showHeaders.zip](showHeaders.zip) |
|
8 | +```perl |
|
9 | +#!/usr/bin/perl |
|
10 | +# HTTP Header の表示 |
|
11 | + |
|
12 | +use strict; |
|
13 | +use warnings; |
|
14 | +use utf8; |
|
15 | +use Encode; |
|
16 | +use LWP::UserAgent; |
|
17 | + |
|
18 | +#my $charsetConsole = 'UTF-8'; # Linux |
|
19 | +my $charsetConsole = 'CP932'; # Windows |
|
20 | +my $charsetFile = 'UTF-8'; |
|
21 | + |
|
22 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
23 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
24 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
25 | + |
|
26 | +my $url = $ARGV[0] or die("usage: showHeaders.pl <URL>\n"); |
|
27 | + |
|
28 | +my $ua = LWP::UserAgent->new; |
|
29 | +my $req = HTTP::Request->new( HEAD => $url ); |
|
30 | + |
|
31 | +# send request |
|
32 | +my $res = $ua->request($req); |
|
33 | +if ( !$res->is_success ) { |
|
34 | + die( "Error: " . $res->status_line . "\n" ); |
|
35 | +} |
|
36 | +foreach my $field ( sort( $res->header_field_names ) ) { |
|
37 | + printf( "%s\t%s\n", $field, $res->header($field) ); |
|
38 | +} |
|
39 | + |
|
40 | +# EOF |
|
41 | +``` |
|
42 | + |
|
43 | +# リンク |
|
44 | +- [CPAN:libwww-perl](http://search.cpan.org/dist/libwww-perl) |
|
45 | +- [CPAN:HTTP-Message](http://search.cpan.org/dist/HTTP-Message) |
|
... | ... | \ No newline at end of file |
Perl/IP\343\202\242\343\203\211\343\203\254\343\202\271\347\257\204\345\233\262\343\202\222\343\203\236\343\202\271\343\202\257\350\241\250\347\217\276\343\201\253\345\244\211\346\217\233.md
... | ... | @@ -0,0 +1,161 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- [IP List for PeerGuardian 2](http://iplist.wave.prohosting.com/)のIPアドレス情報(IP1 - IP2)をマスク表現(IP/mask)に変換します。 |
|
5 | +- IP List for PeerGuardian 2 が公開されなくなったのね。 |
|
6 | +- Net::IP 使わないけど、[世界の国別 IPv4 アドレス割り当てリスト](http://nami.jp/ipv4bycc/)から国別の IP アドレスを抽出するスクリプトを作成。(2013/04/11) |
|
7 | + |
|
8 | +# ソース |
|
9 | +## makeIPBlockList.pl |
|
10 | +- [makeIPBlockList.zip](makeIPBlockList.zip) |
|
11 | +```perl |
|
12 | +#!/usr/bin/perl |
|
13 | +# makeIPBlockList.pl |
|
14 | +# http://iplist.wave.prohosting.com/ のIPリストから接続をブロックするIPアドレスのリストを作成する。 |
|
15 | + |
|
16 | +use strict; |
|
17 | +use warnings; |
|
18 | +use utf8; |
|
19 | +use Encode; |
|
20 | +use Net::IP; |
|
21 | + |
|
22 | +my $fileNameIn = "cn.txt"; |
|
23 | +my $fileNameOut = "cn_block.txt"; |
|
24 | + |
|
25 | +binmode( STDIN, ":encoding(CP932)" ); |
|
26 | +binmode( STDOUT, ":encoding(CP932)" ); |
|
27 | +binmode( STDERR, ":encoding(CP932)" ); |
|
28 | + |
|
29 | +$| = 1; |
|
30 | + |
|
31 | +open( my $fin, "<:utf8", encode( 'CP932', $fileNameIn ) ) or die( "$fileNameIn: $!\n" ); |
|
32 | +my @body = <$fin>; |
|
33 | +close( $fin ); |
|
34 | +chomp( @body ); |
|
35 | + |
|
36 | +open( my $fout, ">:utf8", encode( 'CP932', $fileNameOut ) ) or die( "$fileNameOut: $!\n" ); |
|
37 | + |
|
38 | +my $max = scalar( @body ); |
|
39 | +my $count = 0; |
|
40 | + |
|
41 | +while( @body > 0 ){ |
|
42 | + printf STDERR ( "%d/%d\r", ++$count, $max ); |
|
43 | + my $line = shift( @body ); |
|
44 | + if ( $line =~ /[^:]+:(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)/ ){ |
|
45 | + my $ip = new Net::IP( "$1-$2" ) or die( Net::IP::Error() ); |
|
46 | + foreach ( $ip->find_prefixes() ){ |
|
47 | + /([^\/]+)\/([^\/]+)/; |
|
48 | + printf $fout ( "%s/%s\n", $1, makeMask( $2 ) ); |
|
49 | + } |
|
50 | + } |
|
51 | +} |
|
52 | + |
|
53 | +close( $fout ); |
|
54 | + |
|
55 | +sub makeMask |
|
56 | +{ |
|
57 | + my( $x ) = @_; |
|
58 | + my $ret = ''; |
|
59 | + my $b = "1"; |
|
60 | + while( $x > 0 ){ |
|
61 | + if ( $x & 1 ){ |
|
62 | + $ret .= $b; |
|
63 | + } |
|
64 | + $b .= $b; |
|
65 | + $x >>= 1; |
|
66 | + } |
|
67 | + return join( '.', unpack( 'C*', pack( 'B32', substr( $ret . "00000000000000000000000000000000", 0, 32 ) ) ) ); |
|
68 | +} |
|
69 | + |
|
70 | +# EOF |
|
71 | +``` |
|
72 | + |
|
73 | +### 入力 |
|
74 | +``` |
|
75 | +CN:58.14.0.0-58.25.255.255 |
|
76 | +CN:58.30.0.0-58.63.255.255 |
|
77 | +CN:58.66.0.0-58.67.255.255 |
|
78 | +CN:58.68.128.0-58.68.255.255 |
|
79 | +CN:58.82.0.0-58.83.255.255 |
|
80 | +CN:58.87.64.0-58.87.127.255 |
|
81 | +CN:58.99.128.0-58.101.255.255 |
|
82 | +CN:58.116.0.0-58.119.255.255 |
|
83 | +CN:58.128.0.0-58.135.255.255 |
|
84 | +CN:58.144.0.0-58.144.255.255 |
|
85 | +``` |
|
86 | + |
|
87 | +### 出力 |
|
88 | +``` |
|
89 | +58.14.0.0/255.254.0.0 |
|
90 | +58.16.0.0/255.248.0.0 |
|
91 | +58.24.0.0/255.254.0.0 |
|
92 | +58.30.0.0/255.254.0.0 |
|
93 | +58.32.0.0/255.224.0.0 |
|
94 | +58.66.0.0/255.254.0.0 |
|
95 | +58.68.128.0/255.255.128.0 |
|
96 | +58.82.0.0/255.254.0.0 |
|
97 | +58.87.64.0/255.255.192.0 |
|
98 | +58.99.128.0/255.255.128.0 |
|
99 | +58.100.0.0/255.254.0.0 |
|
100 | +58.116.0.0/255.252.0.0 |
|
101 | +58.128.0.0/255.248.0.0 |
|
102 | +58.144.0.0/255.255.0.0 |
|
103 | +``` |
|
104 | + |
|
105 | +## makeIPBlockList2.pl |
|
106 | +- [makeIPBlockList2.zip](makeIPBlockList2.zip) |
|
107 | +```perl |
|
108 | +#!/usr/bin/perl |
|
109 | +# makeIPBlockList2.pl |
|
110 | +# http://nami.jp/ipv4bycc/mask.txt からアクセス禁止国のIPアドレスを抽出 |
|
111 | + |
|
112 | +use strict; |
|
113 | +use warnings; |
|
114 | +use utf8; |
|
115 | +use Encode; |
|
116 | + |
|
117 | +#my $charset_console = 'UTF-8'; |
|
118 | +my $charset_console = 'CP932'; |
|
119 | +my $charset_file = 'UTF-8'; |
|
120 | + |
|
121 | +binmode( STDIN, ":encoding($charset_console)" ); |
|
122 | +binmode( STDOUT, ":encoding($charset_console)" ); |
|
123 | +binmode( STDERR, ":encoding($charset_console)" ); |
|
124 | + |
|
125 | +my $fileNameIn = 'mask.txt'; |
|
126 | +my $fileNameOut = 'block_list.txt'; |
|
127 | + |
|
128 | +my @countries = qw( CN KR RU BR ); |
|
129 | +my $block_countries = '^(' . join( "|", map{ quotemeta($_); } @countries ) . ')$'; |
|
130 | + |
|
131 | +open( my $fin, "<:encoding($charset_file)", encode( $charset_console, $fileNameIn ) ) |
|
132 | + or die( "$fileNameIn: $!\n" ); |
|
133 | +open( my $fout, ">:encoding($charset_file)", encode( $charset_console, $fileNameOut ) ) |
|
134 | + or die( "$fileNameOut: $!\n" ); |
|
135 | + |
|
136 | +foreach my $line ( <$fin> ){ |
|
137 | + my( $country, $ip ) = split( /\s/, $line ); |
|
138 | + if ( $country =~ /$block_countries/i ){ |
|
139 | + #$ip =~ s{/}{,}; |
|
140 | + printf $fout ( "%s\n", $ip ); |
|
141 | + } |
|
142 | +} |
|
143 | + |
|
144 | +close( $fin ); |
|
145 | +close( $fout ); |
|
146 | + |
|
147 | +# EOF |
|
148 | +``` |
|
149 | + |
|
150 | +# リンク |
|
151 | +- [CPAN:Net-IP](http://search.cpan.org/dist/Net-IP) |
|
152 | + |
|
153 | +- [Office Nami](http://nami.jp/) |
|
154 | + - [世界の国別 IPv4 アドレス割り当てリスト](http://nami.jp/ipv4bycc/) |
|
155 | +- [IP List for PeerGuardian 2](http://iplist.wave.prohosting.com/) |
|
156 | +- [PeerGuardian](http://peerguardian.sourceforge.net/) |
|
157 | + |
|
158 | +- [Perlの数値変換](http://mikeneko.creator.club.ne.jp/~lab/perl/numerical_transform/) |
|
159 | + |
|
160 | +- [iptab と ipcount](http://tkoshima.net/wp/archives/350) |
|
161 | +- [IPCount Tool](http://www.ripe.net/cgi-bin/wwwipcount.cgi) |
|
... | ... | \ No newline at end of file |
Perl/ListDownloader.md
... | ... | @@ -0,0 +1,57 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- 1行に1つ URL が書かれたファイルにしたがって該当ファイルをダウンロードする。 |
|
5 | +- リストファイルがあるフォルダにダウンロードしたファイルを保存する。 |
|
6 | +- アクセス結果を表示するよう変更。(2016-09-12) |
|
7 | + |
|
8 | +# ソース |
|
9 | +- [ListDownloader.zip](ListDownloader.zip) |
|
10 | +```perl |
|
11 | +use strict; |
|
12 | +use warnings; |
|
13 | +use utf8; |
|
14 | +use Encode; |
|
15 | +use File::Basename; |
|
16 | +use File::chdir; |
|
17 | +use LWP::UserAgent; |
|
18 | +use HTTP::Request; |
|
19 | + |
|
20 | +my $charsetConsole = $^O eq 'MSWin32' ? 'CP932' : 'UTF-8'; |
|
21 | + |
|
22 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
23 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
24 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
25 | + |
|
26 | +@ARGV = map { decode( $charsetConsole, $_ ); } @ARGV; |
|
27 | + |
|
28 | +my $charsetFile = 'UTF-8'; |
|
29 | +my $ioLayer = $^O eq 'MSWin32' ? "raw:encoding($charsetFile):crlf" : "encoding($charsetFile)"; |
|
30 | +my $listFile = $ARGV[0] or die("usage: ListDownloader <list file>\n"); |
|
31 | +$CWD = dirname( encode( $charsetConsole, $listFile ) ); |
|
32 | +open( my $fin, "<:$ioLayer", encode( $charsetConsole, $listFile ) ) |
|
33 | + or die("$listFile: $!\n"); |
|
34 | +my @lines = <$fin>; |
|
35 | +close($fin); |
|
36 | +chomp(@lines); |
|
37 | +my %listHash = map { $_ => 1 } @lines; |
|
38 | +my @list = sort( keys(%listHash) ); |
|
39 | + |
|
40 | +my $ua = LWP::UserAgent->new( keep_alive => 4 ); |
|
41 | +$ua->cookie_jar( {} ); |
|
42 | + |
|
43 | +my $count = 0; |
|
44 | +my $max = scalar(@list); |
|
45 | +foreach my $url (@list) { |
|
46 | + ++$count; |
|
47 | + $url =~ m{([^\/]+)$}; |
|
48 | + my $filename = $1; |
|
49 | + print "$count/$max\t$filename\n"; |
|
50 | + my $res |
|
51 | + = $ua->request( HTTP::Request->new( GET => $url ), encode( $charsetConsole, $filename ) ); |
|
52 | + sleep(1); |
|
53 | +} |
|
54 | +``` |
|
55 | + |
|
56 | +# リンク |
|
57 | +- [CPAN:perl/lib/File/Basename.pm](http://search.cpan.org/dist/perl/lib/File/Basename.pm) |
|
... | ... | \ No newline at end of file |
Perl/MSSQL_ImpExp.md
... | ... | @@ -0,0 +1,464 @@ |
1 | +# Microsoft SQL Server インポート/エクスポート |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- MS SQL Server のテーブルを CSV ファイル(K3フォーマット)としてインポート/エクスポートする。 |
|
6 | +- 第1フィールドをプライマリフィールドとして、レコードが未登録か登録済みかを判別し、INSERT または UPDATE を行なう。 |
|
7 | +- NULLは「NULL」として書き出される。文字列としてのNULLは「"NULL"」になる。 |
|
8 | +- INDEX(オートナンバー)制約があるフィールドには未対応(ハングアップする)。(2011/09/28) |
|
9 | + |
|
10 | +## ソースコード |
|
11 | +- [MSSQL_ImpExp.zip](MSSQL_ImpExp.zip) |
|
12 | + |
|
13 | +### DB_Connect.yaml |
|
14 | +``` |
|
15 | +# DB接続情報 |
|
16 | +Driver: ODBC |
|
17 | +Server: localhost\SQLEXPRESS,1433 # <サーバ名>\<インスタンス名>[,<ポート番号>] |
|
18 | +User: TestUser |
|
19 | +Password: "TestPass" # 記号を含む場合は""で括る。 |
|
20 | +DB: TestDB |
|
21 | +Options: |
|
22 | + LongTruncOk: 1 |
|
23 | + LongReadLen: 8192 |
|
24 | +DSN: _Driver_:Driver={SQL Server}; Server={_Server_}; Database=_DB_; |
|
25 | +``` |
|
26 | + |
|
27 | +### getSchema.pl |
|
28 | +```perl |
|
29 | +#!/usr/bin/perl |
|
30 | +# MSSQLサーバからスキーマを読み出す |
|
31 | + |
|
32 | +use strict; |
|
33 | +use warnings; |
|
34 | +use utf8; |
|
35 | +use Encode; |
|
36 | +use YAML::Syck; |
|
37 | +use FindBin::libs; |
|
38 | +use DBIx::NamedParams; |
|
39 | + |
|
40 | +$YAML::Syck::ImplicitUnicode = 1; |
|
41 | + |
|
42 | +my $charsetConsole = 'CP932'; |
|
43 | +my $charsetFile = 'UTF-8'; |
|
44 | + |
|
45 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
46 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
47 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
48 | + |
|
49 | +my $DB_Connect_yaml = './DB_Connect.yaml'; |
|
50 | +my $DB_Schema_yaml = './DB_Schema.yaml'; |
|
51 | + |
|
52 | +my @SchemaColumns = qw( |
|
53 | + COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH COLUMN_DEFAULT IS_NULLABLE |
|
54 | +); |
|
55 | + |
|
56 | +$| = 1; |
|
57 | + |
|
58 | +my $Schemas = {}; |
|
59 | + |
|
60 | +my $DB_Connect = YAML::Syck::LoadFile( $DB_Connect_yaml ) |
|
61 | + or die( "$DB_Connect_yaml: $!" ); |
|
62 | +foreach( keys( %{$DB_Connect} ) ){ |
|
63 | + $DB_Connect->{'DSN'} =~ s/_${_}_/$DB_Connect->{$_}/; |
|
64 | +} |
|
65 | +#print Dump( $DB_Connect ); |
|
66 | +#exit; |
|
67 | + |
|
68 | +my $dbh = DBI->connect( |
|
69 | + "DBI:" . $DB_Connect->{'DSN'}, |
|
70 | + $DB_Connect->{'User'}, |
|
71 | + $DB_Connect->{'Password'}, |
|
72 | + $DB_Connect->{'Options'} |
|
73 | +) or die( "$DBI::errstr\n" ); |
|
74 | +#print Dump( $dbh ); |
|
75 | +#exit; |
|
76 | + |
|
77 | +my $DBName = $DB_Connect->{'DB'}; |
|
78 | +my $sql_getTables = qq{ |
|
79 | + SELECT [TABLE_NAME] |
|
80 | + FROM [INFORMATION_SCHEMA].[TABLES] |
|
81 | + WHERE [TABLE_CATALOG] = '$DBName' |
|
82 | + and [TABLE_TYPE]='BASE TABLE' |
|
83 | + ORDER BY [TABLE_NAME]; |
|
84 | +}; |
|
85 | +my $sth = $dbh->prepare( $sql_getTables ) or die( "$DBI::errstr\n" ); |
|
86 | +$sth->execute() or die( "$DBI::errstr\n" ); |
|
87 | + |
|
88 | +do { |
|
89 | + while( my @a = $sth->fetchrow_array ){ |
|
90 | + #printf( "%s\n", join( "\t", @a ) ); |
|
91 | + $Schemas->{ $a[0] } = []; |
|
92 | + } |
|
93 | +}while( $sth->{odbc_more_results} ); |
|
94 | +$sth->finish; |
|
95 | + |
|
96 | +my @TableNames = sort( keys( %{ $Schemas } ) ); |
|
97 | +#print "Tables: " . scalar(@TableNames) ."\n"; |
|
98 | +#print join( "\n", DBIx::NamedParams::all_sql_types() ) . "\n"; |
|
99 | +#exit; |
|
100 | + |
|
101 | +$_ = '[' . join( "], [", @SchemaColumns ) . ']'; |
|
102 | +my $sql_getColumns = qq{ |
|
103 | + SELECT $_ |
|
104 | + FROM [INFORMATION_SCHEMA].[COLUMNS] |
|
105 | + WHERE [TABLE_CATALOG] = '$DBName' |
|
106 | + and [TABLE_NAME] = :TableName-WVARCHAR |
|
107 | +}; |
|
108 | +$sth = $dbh->prepare_ex( $sql_getColumns ) or die( "$DBI::errstr\n" ); |
|
109 | + |
|
110 | +my $count = 0; |
|
111 | +foreach my $tbl ( @TableNames ){ |
|
112 | + printf( "%d/%d\t%s\n", ++$count, scalar(@TableNames), $tbl ); |
|
113 | + my @columns = (); |
|
114 | + $sth->bind_param_ex( { 'TableName' => $tbl } ); |
|
115 | + $sth->execute() or die( "$DBI::errstr\n" ); |
|
116 | + do { |
|
117 | + while( my @a = $sth->fetchrow_array ){ |
|
118 | + #printf( "%s\n", join( "\t", @a ) ); |
|
119 | + my $ColumnsInfo = {}; |
|
120 | + for( my $i=0; $i<@SchemaColumns; ++$i ){ |
|
121 | + $ColumnsInfo->{ $SchemaColumns[ $i ] } = $a[ $i ]; |
|
122 | + } |
|
123 | + push( @columns, $ColumnsInfo ); |
|
124 | + } |
|
125 | + }while( $sth->{odbc_more_results} ); |
|
126 | + $Schemas->{ $tbl } = [ @columns ]; |
|
127 | +} |
|
128 | +$sth->finish; |
|
129 | + |
|
130 | +$dbh->disconnect; |
|
131 | + |
|
132 | +open( my $fhout, ">:utf8", encode( $charsetConsole, $DB_Schema_yaml ) ) |
|
133 | + or die( "$DB_Schema_yaml: $!\n" ); |
|
134 | +print $fhout YAML::Syck::Dump( $Schemas ); |
|
135 | +#print dump( $Schemas ); |
|
136 | +close( $fhout ); |
|
137 | + |
|
138 | +# EOF |
|
139 | +``` |
|
140 | + |
|
141 | +### getTbl.pl |
|
142 | +```perl |
|
143 | +#!/usr/bin/perl |
|
144 | +# MSSQLサーバからデータ読み出し |
|
145 | + |
|
146 | +use strict; |
|
147 | +use warnings; |
|
148 | +use utf8; |
|
149 | +use Encode; |
|
150 | +use YAML::Syck; |
|
151 | +use FindBin::libs; |
|
152 | +use DBIx::NamedParams; |
|
153 | +use EscapeSlash; |
|
154 | + |
|
155 | +$YAML::Syck::ImplicitUnicode = 1; |
|
156 | + |
|
157 | +my $charsetConsole = 'CP932'; |
|
158 | +my $charsetFile = 'UTF-8'; |
|
159 | + |
|
160 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
161 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
162 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
163 | + |
|
164 | +my $DB_Connect_yaml = './DB_Connect.yaml'; |
|
165 | +my $DB_Tables_yaml = './DB_Schema.yaml'; |
|
166 | + |
|
167 | +# ""で括る文字列型 |
|
168 | +my $StrType = join( "|", qw( |
|
169 | + CHAR GUID UNKNOWN_TYPE VARCHAR WCHAR WLONGVARCHAR WVARCHAR |
|
170 | +) ); |
|
171 | + |
|
172 | +my $DB_Connect = YAML::Syck::LoadFile( $DB_Connect_yaml ) |
|
173 | + or die( "$DB_Connect_yaml: $!\n" ); |
|
174 | +foreach( %{$DB_Connect} ){ |
|
175 | + $DB_Connect->{'DSN'} =~ s/_${_}_/$DB_Connect->{$_}/; |
|
176 | +} |
|
177 | +#print dump( $DB_Connect ); |
|
178 | + |
|
179 | +my $DB_Tables = YAML::Syck::LoadFile( $DB_Tables_yaml ) |
|
180 | + or die( "$DB_Tables_yaml: $!\n" ); |
|
181 | +#print dump( $DB_Tables ); |
|
182 | +my @DB_TableNames = sort( keys( %{$DB_Tables} ) ); |
|
183 | + |
|
184 | +my $dbh = DBI->connect( |
|
185 | + "DBI:" . $DB_Connect->{'DSN'}, |
|
186 | + $DB_Connect->{'User'}, |
|
187 | + $DB_Connect->{'Password'}, |
|
188 | + $DB_Connect->{'Options'} |
|
189 | +) or die( "$DBI::errstr\n" ); |
|
190 | + |
|
191 | +my %DrvTypeToSQLType = $dbh->driver_typename_map(); |
|
192 | + |
|
193 | +my $count=0; |
|
194 | +my $TableNum = scalar(@DB_TableNames); |
|
195 | + |
|
196 | +foreach my $tbl ( @DB_TableNames ){ |
|
197 | + printf STDERR ( "%d/%d\t%s\n", ++$count, $TableNum, $tbl ); |
|
198 | + my @FieldName = map { ${$_ }{'COLUMN_NAME'}; } @{ $DB_Tables->{ $tbl } }; |
|
199 | + my @DataType = map { ${$_ }{'DATA_TYPE'}; } @{ $DB_Tables->{ $tbl } }; |
|
200 | + |
|
201 | + my $sql = "SELECT [" . join( "],[", @FieldName ) . "] FROM [$tbl];"; |
|
202 | + my $sth = $dbh->prepare( $sql ) or die( "$DBI::errstr\n" ); |
|
203 | + $sth->execute() or die( "$DBI::errstr\n" ); |
|
204 | + |
|
205 | + my $fout = './_DB/' . $tbl . '.txt'; |
|
206 | + open( my $fhout, ">:encoding($charsetFile)", encode( $charsetConsole, $fout ) ) |
|
207 | + or die( "$fout: $!\n" ); |
|
208 | + |
|
209 | + printf $fhout ( "\"%s\"\n", join( "\"\t\"", @FieldName ) ); |
|
210 | + do { |
|
211 | + while( my @a = $sth->fetchrow_array ){ |
|
212 | + for( my $i=0; $i<@a; ++$i ){ |
|
213 | + no warnings 'uninitialized'; |
|
214 | + $a[$i] =~ s/\x00//g; |
|
215 | + #$a[$i] =~ s/[\r\n\t]+$//; |
|
216 | + $a[$i] = escapeslash( $a[$i] ); |
|
217 | + if ( !defined($a[$i]) ){ |
|
218 | + # NULL だったら |
|
219 | + $a[$i] = "NULL"; |
|
220 | + } elsif ( $DrvTypeToSQLType{ $DataType[$i] } =~ /$StrType/ ){ |
|
221 | + # 文字列ならば |
|
222 | + $a[$i] = '"' . $a[$i] . '"'; |
|
223 | + } |
|
224 | + } |
|
225 | + printf $fhout ( "%s\n", join( "\t", @a ) ); |
|
226 | + } |
|
227 | + }while( $sth->{odbc_more_results} ); |
|
228 | + $sth->finish; |
|
229 | + |
|
230 | + close( $fhout ); |
|
231 | +} |
|
232 | + |
|
233 | +$dbh->disconnect; |
|
234 | + |
|
235 | +# EOF |
|
236 | +``` |
|
237 | + |
|
238 | +### setTbl.pl |
|
239 | +```perl |
|
240 | +#!/usr/bin/perl |
|
241 | +# MSSQLサーバへデータ書込み |
|
242 | +# 2011/09/28 オートナンバー型非対応 |
|
243 | + |
|
244 | +use strict; |
|
245 | +use warnings; |
|
246 | +use utf8; |
|
247 | +use Encode; |
|
248 | +use YAML::Syck; |
|
249 | +use FindBin::libs; |
|
250 | +use DBIx::NamedParams; |
|
251 | +use EscapeSlash; |
|
252 | + |
|
253 | +$YAML::Syck::ImplicitUnicode = 1; |
|
254 | + |
|
255 | +my $charsetConsole = 'CP932'; |
|
256 | +my $charsetFile = 'UTF-8'; |
|
257 | + |
|
258 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
259 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
260 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
261 | + |
|
262 | +my $DB_Connect_yaml = './DB_Connect.yaml'; |
|
263 | +my $DB_Tables_yaml = './DB_Schema.yaml'; |
|
264 | + |
|
265 | +my $DB_Connect = YAML::Syck::LoadFile( $DB_Connect_yaml ) |
|
266 | + or die( "$DB_Connect_yaml: $!" ); |
|
267 | +foreach( %{$DB_Connect} ){ |
|
268 | + $DB_Connect->{'DSN'} =~ s/_${_}_/$DB_Connect->{$_}/; |
|
269 | +} |
|
270 | +#print Dump( $DB_Connect ); |
|
271 | + |
|
272 | +my $DB_Tables = YAML::Syck::LoadFile( $DB_Tables_yaml ) |
|
273 | + or die( "$DB_Tables_yaml: $!" ); |
|
274 | +#print Dump( $DB_Tables ); |
|
275 | +my @DB_TableNames = keys( %{$DB_Tables} ); |
|
276 | + |
|
277 | +my $dbh = DBI->connect( |
|
278 | + "DBI:" . $DB_Connect->{'DSN'}, |
|
279 | + $DB_Connect->{'User'}, |
|
280 | + $DB_Connect->{'Password'}, |
|
281 | + $DB_Connect->{'Options'} |
|
282 | +) or die( "$DBI::errstr\n" ); |
|
283 | + |
|
284 | +#DBIx::NamedParams::debug_log( 'MSSQL_ImpExp.log' ); |
|
285 | + |
|
286 | +my %DrvTypeToSQLType = $dbh->driver_typename_map(); |
|
287 | + |
|
288 | +my $count=0; |
|
289 | +my $TableNum = scalar(@DB_TableNames); |
|
290 | +my $fNoLocalize = 0; |
|
291 | + |
|
292 | +foreach my $tbl ( @DB_TableNames ){ |
|
293 | + ++$count; |
|
294 | + print "$count/$TableNum\t$tbl\n"; |
|
295 | + my( @field_org, @field_len, @field_type, @field_name_type, @field_prm ); |
|
296 | + foreach ( @{ $DB_Tables->{ $tbl } } ){ |
|
297 | + my $column_name = ${ $_ }{'COLUMN_NAME'}; |
|
298 | + my $data_type = ${ $_ }{'DATA_TYPE'}; |
|
299 | + my $name_type = ":$column_name-" . $DrvTypeToSQLType{ $data_type }; |
|
300 | + push( @field_org, $column_name ); |
|
301 | + push( @field_type, $data_type ); |
|
302 | + push( @field_len, ${ $_ }{'CHARACTER_MAXIMUM_LENGTH'} ); |
|
303 | + push( @field_name_type, $name_type ); |
|
304 | + push( @field_prm, "[$column_name]=$name_type" ); |
|
305 | + } |
|
306 | + my $i = 0; |
|
307 | + my %FN2I = map{ s/^"(.*)"$/$1/; $_ => $i++; } @field_org; |
|
308 | + #print Dump( \%FN2I ); |
|
309 | + |
|
310 | + my $FieldList = "[" . join( "],[", @field_org ) . "]"; |
|
311 | + my $ValueList = join( ",", @field_name_type ); |
|
312 | + my $UpdateList = join( ",", @field_prm ); |
|
313 | + |
|
314 | + my $PrimaryFieldName = $field_org[0]; |
|
315 | + my $PrimaryFieldNameType = $field_name_type[0]; |
|
316 | + my $sql_InsOrUpd = qq{ |
|
317 | + IF NOT EXISTS ( |
|
318 | + SELECT $FieldList |
|
319 | + FROM [$tbl] |
|
320 | + WHERE [$PrimaryFieldName] = $PrimaryFieldNameType |
|
321 | + ) |
|
322 | + BEGIN |
|
323 | + INSERT INTO [$tbl] |
|
324 | + ($FieldList) |
|
325 | + VALUES ($ValueList) |
|
326 | + END |
|
327 | + ELSE |
|
328 | + BEGIN |
|
329 | + UPDATE [$tbl] |
|
330 | + SET $UpdateList |
|
331 | + WHERE [$PrimaryFieldName] = $PrimaryFieldNameType |
|
332 | + END; |
|
333 | + }; |
|
334 | + #warn "$sql_InsOrUpd\n"; |
|
335 | + #exit(); |
|
336 | + |
|
337 | + my $sth = $dbh->prepare_ex( $sql_InsOrUpd ) |
|
338 | + or die( "$DBI::errstr\n" ); |
|
339 | + |
|
340 | + my $fin = './_DB/' . $tbl . '.txt'; |
|
341 | + open( my $fhin, "<:encoding($charsetFile)", encode( $charsetConsole, $fin ) ) |
|
342 | + or die( "$fin: $!\n" ); |
|
343 | + <$fhin>; # ヘッダ行を捨てる |
|
344 | + my @DB_Body = <$fhin>; |
|
345 | + close( $fhin ); |
|
346 | + chomp( @DB_Body ); |
|
347 | + |
|
348 | + foreach my $row ( @DB_Body ){ |
|
349 | + #warn $row."\n"; |
|
350 | + my @param = split( "\t", $row ); |
|
351 | + map{ if( /^NULL$/i ){ undef($_) } else { s/^"(.*)"$/$1/; } } @param; |
|
352 | + for( my $i=0; $i<@param; ++$i ){ |
|
353 | + if ( |
|
354 | + $field_len[ $i ] && ( $field_len[ $i ] > 0 ) |
|
355 | + && $param[ $i ] && ( length( $param[ $i ] ) > $field_len[ $i ] ) |
|
356 | + ){ |
|
357 | + print "Too long. ID:$param[0], $field_org[$i]: $param[$i]\n"; |
|
358 | + $param[ $i ] = substr( $param[ $i ], 0, $field_len[ $i ] ); |
|
359 | + } |
|
360 | + } |
|
361 | + my %bind = (); |
|
362 | + for( my $i=0; $i<@field_org; ++$i ){ |
|
363 | + $bind{ $field_org[ $i ] } = unescapeslash( $param[ $i ] ); |
|
364 | + } |
|
365 | + #print Dump( \%bind ) ."\n"; |
|
366 | + $sth->bind_param_ex( \%bind ); |
|
367 | + #exit(); |
|
368 | + $sth->execute() or die( "$DBI::errstr\n" ); |
|
369 | + } |
|
370 | + $sth->finish; |
|
371 | +} |
|
372 | +$dbh->disconnect; |
|
373 | + |
|
374 | +# EOF |
|
375 | +``` |
|
376 | + |
|
377 | +### makeTable.sql |
|
378 | +``` |
|
379 | +USE [TestDB] |
|
380 | +GO |
|
381 | + |
|
382 | +/****** Object: Table [dbo].[会員Table] Script Date: 08/15/2009 04:13:13 ******/ |
|
383 | +SET ANSI_NULLS ON |
|
384 | +GO |
|
385 | + |
|
386 | +SET QUOTED_IDENTIFIER ON |
|
387 | +GO |
|
388 | + |
|
389 | +CREATE TABLE [dbo].[会員Table]( |
|
390 | + [ID] [int] NOT NULL, |
|
391 | + [姓] [nvarchar](50) NOT NULL, |
|
392 | + [名] [nvarchar](50) NOT NULL, |
|
393 | + [誕生日] [date] NOT NULL, |
|
394 | + [性別] [int] NOT NULL, |
|
395 | + [Email] [nvarchar](50) NULL, |
|
396 | + [電話番号] [nvarchar](50) NULL, |
|
397 | + [郵便番号] [nvarchar](8) NULL, |
|
398 | + [住所1] [nvarchar](max) NULL, |
|
399 | + [住所2] [nvarchar](max) NULL, |
|
400 | + [クラスレベル] [int] NOT NULL, |
|
401 | + [前回ログイン] [datetime] NULL, |
|
402 | + [備考] [nvarchar](max) NULL, |
|
403 | + CONSTRAINT [PK_会員Table] PRIMARY KEY CLUSTERED |
|
404 | +( |
|
405 | + [ID] ASC |
|
406 | +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] |
|
407 | +) ON [PRIMARY] |
|
408 | + |
|
409 | +GO |
|
410 | + |
|
411 | +/****** Object: Table [dbo].[性別Table] Script Date: 08/15/2009 04:13:59 ******/ |
|
412 | +SET ANSI_NULLS ON |
|
413 | +GO |
|
414 | + |
|
415 | +SET QUOTED_IDENTIFIER ON |
|
416 | +GO |
|
417 | + |
|
418 | +CREATE TABLE [dbo].[性別Table]( |
|
419 | + [ID] [int] NOT NULL, |
|
420 | + [性別] [nvarchar](10) NOT NULL, |
|
421 | + CONSTRAINT [PK_性別Table] PRIMARY KEY CLUSTERED |
|
422 | +( |
|
423 | + [ID] ASC |
|
424 | +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] |
|
425 | +) ON [PRIMARY] |
|
426 | + |
|
427 | +GO |
|
428 | + |
|
429 | +/****** Object: Table [dbo].[クラスレベルTable] Script Date: 08/15/2009 04:14:09 ******/ |
|
430 | +SET ANSI_NULLS ON |
|
431 | +GO |
|
432 | + |
|
433 | +SET QUOTED_IDENTIFIER ON |
|
434 | +GO |
|
435 | + |
|
436 | +CREATE TABLE [dbo].[クラスレベルTable]( |
|
437 | + [ID] [int] NOT NULL, |
|
438 | + [クラスレベル] [nvarchar](30) NOT NULL, |
|
439 | + CONSTRAINT [PK_クラスレベルTable] PRIMARY KEY CLUSTERED |
|
440 | +( |
|
441 | + [ID] ASC |
|
442 | +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] |
|
443 | +) ON [PRIMARY] |
|
444 | + |
|
445 | +GO |
|
446 | +``` |
|
447 | + |
|
448 | +## Link |
|
449 | +- [[MS SQL Server|MSSQLSrv]] |
|
450 | +- [[Perl/EscapeSlash]] |
|
451 | +- [[Perl/DBIx-NamedParams]] |
|
452 | +- [[Perl/キーワード置換]] |
|
453 | + |
|
454 | +- [SQL Server - 情報スキーマ ビュー](http://msdn.microsoft.com/ja-jp/library/ms186778.aspx) |
|
455 | + - [TABLES](http://msdn.microsoft.com/ja-jp/library/ms186224.aspx) |
|
456 | + - [COLUMNS](http://msdn.microsoft.com/ja-jp/library/ms188348.aspx) |
|
457 | +- [sys.columns](http://msdn.microsoft.com/ja-jp/library/ms176106.aspx) |
|
458 | +- [データ型](http://msdn.microsoft.com/ja-jp/library/ms187752.aspx) |
|
459 | + |
|
460 | +- [MDB生成/テーブル定義取得ツール](http://www.asahi-net.or.jp/~ef2o-inue/download/sub09_010_070.html) |
|
461 | + |
|
462 | +- [「IDENTITY属性を持つ列を探すには」をお題にやったことをBlogる](http://d.hatena.ne.jp/CAMUSs_BLACKBOARD/20040618) @ [CAMUS’s BLACKBOARD](http://d.hatena.ne.jp/CAMUSs_BLACKBOARD/) |
|
463 | +``` |
|
464 | +EXEC sp_MShelpcolumns [テーブル名] |
|
... | ... | \ No newline at end of file |
Perl/MailForm.md
... | ... | @@ -0,0 +1,333 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- ファイルが添付できるメールフォーム。 |
|
5 | +- 宛先は config.yaml で指定する。フォームから宛先の追加も可能。 |
|
6 | +- 名前, 宛先は Cookie に保存される。(1ヶ月) |
|
7 | +- アクセス元のホスト名を表示。 |
|
8 | +- cookie の path を設定。 |
|
9 | + |
|
10 | +# ソース |
|
11 | +- [MailForm.zip](MailForm.zip) |
|
12 | + |
|
13 | +## index.cgi |
|
14 | +```perl |
|
15 | +#!/usr/bin/perl |
|
16 | +# MailForm |
|
17 | +# Web フォームから入力されたコメントとファイルを、 |
|
18 | +# 特定の Email アドレスへ添付ファイル付きで送信する。 |
|
19 | + |
|
20 | +use strict; |
|
21 | +use warnings; |
|
22 | +use utf8; |
|
23 | +use Encode; |
|
24 | +use YAML::Syck; |
|
25 | +use JSON::Syck; |
|
26 | +use FindBin; |
|
27 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
28 | +use CGI::Cookie; |
|
29 | +use Email::Sender::Simple qw( sendmail ); |
|
30 | +use Email::Sender::Transport::SMTP; |
|
31 | +use Email::MIME; |
|
32 | +use Email::MIME::Creator; |
|
33 | +use Net::DNS::Resolver; |
|
34 | + |
|
35 | +$YAML::Syck::ImplicitUnicode = 1; |
|
36 | +$YAML::Syck::ImplicitTyping = 1; |
|
37 | +$YAML::Syck::Headless = 1; |
|
38 | +$JSON::Syck::ImplicitUnicode = 1; |
|
39 | + |
|
40 | +my $charset_console = 'UTF-8'; |
|
41 | +my $charset_file = 'UTF-8'; |
|
42 | +my $charset_input = 'UTF-8'; |
|
43 | + |
|
44 | +#binmode( STDIN, ":encoding($charset_console)" ); # バイナリファイルが化ける |
|
45 | +binmode( STDIN, ":raw" ); # バイナリファイルをアップロードする場合に必要 |
|
46 | +binmode( STDOUT, ":encoding($charset_console)" ); |
|
47 | +binmode( STDERR, ":encoding($charset_console)" ); |
|
48 | + |
|
49 | +my $base_path = $FindBin::RealBin . '/'; |
|
50 | +my $config_file = $base_path . 'config.yaml'; |
|
51 | +my $cgi_name = 'MailForm'; |
|
52 | +my $cookie_name = $cgi_name; |
|
53 | + |
|
54 | +my $q = new CGI; |
|
55 | +$q->charset( $charset_console ); |
|
56 | +my $br = $q->br(); |
|
57 | + |
|
58 | +$JSON::Syck::ImplicitUnicode = 1; |
|
59 | +my $cookies = CGI::Cookie->fetch; |
|
60 | +my $cookie = ( $cookies && $cookies->{$cookie_name} ) |
|
61 | + ? JSON::Syck::Load( $cookies->{$cookie_name}->value || '{}' ) |
|
62 | + : {} ; |
|
63 | +# クッキーにゴミデータが入っていた場合に消去 |
|
64 | +if ( ref( $cookie ) ne 'HASH' ){ |
|
65 | + $cookie = {}; |
|
66 | +} |
|
67 | + |
|
68 | +my $config = YAML::Syck::LoadFile( $config_file ) or die( "$config_file: $!\n" ); |
|
69 | + |
|
70 | +my $command = $q->param( 'Command' ) || ''; |
|
71 | +my $comment = decode( $charset_input, $q->param( 'Comment' ) || '' ); |
|
72 | +my $file_name = $q->param( 'Attachment' ) || ''; |
|
73 | +my $file_type = $q->uploadInfo( $file_name ) |
|
74 | + ? $q->uploadInfo( $file_name )->{ 'Content-Type' } || '' |
|
75 | + : ''; |
|
76 | +$file_name = decode( $charset_input, $file_name ); |
|
77 | +my $file_body = ''; |
|
78 | +if ( my $lightweight_fh = $q->upload( 'Attachment' ) ){ |
|
79 | + my $io_handle = $lightweight_fh->handle; |
|
80 | + while ( my $bytesread = $io_handle->read( my $buffer, 1024 ) ){ |
|
81 | + $file_body .= $buffer; |
|
82 | + } |
|
83 | +} |
|
84 | +my $user_name = decode( $charset_input, $q->param( 'UserName' ) || '' ) |
|
85 | + || $cookie->{ 'UserName' } || ''; |
|
86 | +my $user_email = decode( $charset_input, $q->param( 'UserEmail' ) || '' ) |
|
87 | + || $cookie->{ 'UserEmail' } || ''; |
|
88 | + |
|
89 | +$cookie = { |
|
90 | + 'UserName' => $user_name, |
|
91 | + 'UserEmail' => $user_email, |
|
92 | +}; |
|
93 | + |
|
94 | +my $remote_ip = $ENV{ 'REMOTE_ADDR' }; |
|
95 | +my $remote_name = getHostName( $remote_ip ); |
|
96 | + |
|
97 | +print makeHeader(); |
|
98 | +if ( $command eq 'doPost' ){ |
|
99 | + my $mail_result; |
|
100 | + if ( length( $file_body ) > 0 ){ |
|
101 | + $mail_result = sendMail(); |
|
102 | + } |
|
103 | + print showPostedInfo(); |
|
104 | +} else { |
|
105 | + print makeForm(); |
|
106 | +} |
|
107 | +print makeFooter(); |
|
108 | + |
|
109 | +exit; |
|
110 | + |
|
111 | +sub makeHeader |
|
112 | +{ |
|
113 | + my $ret = ''; |
|
114 | + $JSON::Syck::ImplicitUnicode = 0; |
|
115 | + my $cookie_header = CGI::Cookie->new( |
|
116 | + -name => $cookie_name, |
|
117 | + -value => JSON::Syck::Dump( $cookie ), |
|
118 | + -expires => '+1M', |
|
119 | + -path => $ENV{'REQUEST_URI'}, |
|
120 | + ); |
|
121 | + $ret .= $q->header( -cookie => [ $cookie_header ] ); |
|
122 | + $ret .= $q->start_html( |
|
123 | + -title => $cgi_name, |
|
124 | + -lang => 'ja-JP', |
|
125 | + -head => [ |
|
126 | + $q->meta( { -http_equiv => 'Content-style-type', -content => 'text/css' } ), |
|
127 | + $q->meta( { -http_equiv => 'Content-script-type', -content => 'text/javascript' } ), |
|
128 | + ], |
|
129 | + -style => [ { -src => $config->{ 'CSSFile' } }, ], |
|
130 | + ); |
|
131 | + $ret .= $q->h1( $q->a( { -href => $q->url }, $cgi_name ) ); |
|
132 | +# $ret .= $q->pre( YAML::Syck::Dump( $cookie ) ); |
|
133 | + return $ret; |
|
134 | +} |
|
135 | + |
|
136 | +sub makeFooter |
|
137 | +{ |
|
138 | + my $ret = ''; |
|
139 | + $ret .= $q->end_html . "\n"; |
|
140 | + return $ret; |
|
141 | +} |
|
142 | + |
|
143 | +sub makeForm |
|
144 | +{ |
|
145 | + my $ret = ''; |
|
146 | + $ret .= $q->start_multipart_form( -action => $q->url, ); |
|
147 | + $ret .= $q->table( |
|
148 | + $q->Tr( |
|
149 | + $q->th( '名前' ), |
|
150 | + $q->td( $q->textfield( |
|
151 | + -name => 'UserName', |
|
152 | + -default => $user_name, |
|
153 | + -size => 60, |
|
154 | + -override => 1, |
|
155 | + ) ), |
|
156 | + ), |
|
157 | + $q->Tr( |
|
158 | + $q->th( 'Email' ), |
|
159 | + $q->td( $q->textfield( |
|
160 | + -name => 'UserEmail', |
|
161 | + -default => $user_email, |
|
162 | + -size => 60, |
|
163 | + -override => 1, |
|
164 | + ) ), |
|
165 | + ), |
|
166 | + $q->Tr( |
|
167 | + $q->th( '添付ファイル' ), |
|
168 | + $q->td( $q->filefield( |
|
169 | + -name => 'Attachment', |
|
170 | + -default => '', |
|
171 | + -size => 60, |
|
172 | + -override => 1, |
|
173 | + ) ), |
|
174 | + ), |
|
175 | + $q->Tr( |
|
176 | + $q->th( 'コメント' ), |
|
177 | + $q->td( $q->textarea( |
|
178 | + -name => 'Comment', |
|
179 | + -default => '', |
|
180 | + -columns => 60, |
|
181 | + -rows => 5, |
|
182 | + -override => 1, |
|
183 | + ) ), |
|
184 | + ), |
|
185 | + $q->Tr( |
|
186 | + $q->th( 'アクセス元' ), |
|
187 | + $q->td( "$remote_ip; $remote_name" ), |
|
188 | + ), |
|
189 | + $q->Tr( $q->td( |
|
190 | + { -colspan => 2, -align => 'center', }, |
|
191 | + $q->submit( -name => 'Submit', -value => 'Submit' ), |
|
192 | + ), ), |
|
193 | + ); |
|
194 | + $ret .= $q->hidden( -name => 'Command', -default => 'doPost', -override => 1 ); |
|
195 | + $ret .= $q->end_multipart_form; |
|
196 | + return $ret; |
|
197 | +} |
|
198 | + |
|
199 | +sub showPostedInfo |
|
200 | +{ |
|
201 | + my $ret = ''; |
|
202 | + $ret .= $q->table( |
|
203 | + $q->Tr( $q->th( '名前' ), $q->td( $user_name ), ), |
|
204 | + $q->Tr( $q->th( 'Email' ), $q->td( $user_email ), ), |
|
205 | + $q->Tr( $q->th( 'コメント' ), $q->td( $comment ), ), |
|
206 | + $q->Tr( $q->th( 'アクセス元' ), $q->td( "$remote_ip; $remote_name" ), ), |
|
207 | + $q->Tr( $q->th( 'ファイル名' ), $q->td( $file_name ), ), |
|
208 | + $q->Tr( $q->th( 'ファイルタイプ' ), $q->td( $file_type ), ), |
|
209 | + $q->Tr( $q->th( 'ファイルサイズ' ), $q->td( length( $file_body ), ), ), |
|
210 | + $q->Tr( $q->th( 'Hex' ), $q->td( dumpStr( $file_body ) ), ), |
|
211 | + ); |
|
212 | + return $ret; |
|
213 | +} |
|
214 | + |
|
215 | +sub dumpStr |
|
216 | +{ |
|
217 | + my $dump_limit = 64; |
|
218 | + my $str = shift || ''; |
|
219 | + my $head = shift || $dump_limit; |
|
220 | + if ( $head > $dump_limit ){ |
|
221 | + $head = $dump_limit; |
|
222 | + } |
|
223 | + if ( $head > length( $str ) ){ |
|
224 | + $head = length( $str ); |
|
225 | + } |
|
226 | + $str = substr( $str, 0, $head ); |
|
227 | + my $ret = ''; |
|
228 | + my @buffer = (); |
|
229 | + for( my $i=0; $i<$head; $i+=16 ){ |
|
230 | + for( my $j=0; $j<16 && ( $i + $j < $head ); ++$j ){ |
|
231 | + push( @buffer, unpack( "H*", substr( $str, $i + $j, 1 ) ) ); |
|
232 | + } |
|
233 | + push( @buffer, $br ); |
|
234 | + } |
|
235 | + $ret = join( " ", @buffer ); |
|
236 | + return $ret; |
|
237 | +} |
|
238 | + |
|
239 | +sub sendMail |
|
240 | +{ |
|
241 | + my $body = "名前:\n${user_name}\n\nEmail:\n${user_email}\n\nコメント:\n${comment}\n\n" |
|
242 | + . "アクセス元:\n${remote_ip}; ${remote_name}\n\n"; |
|
243 | + my $email = Email::MIME->create( |
|
244 | + attributes => { |
|
245 | + content_type => 'text/plain', |
|
246 | + charset => 'UTF-8', |
|
247 | + encoding => '8bit', |
|
248 | + #encoding => 'base64', |
|
249 | + }, |
|
250 | + header_str => [ |
|
251 | + From => $config->{ 'FromAddress' }, |
|
252 | + To => join( ", ", $config->{ 'ToAddress' }, $user_email, ) , |
|
253 | + Subject => $config->{ 'MailTitle' }, |
|
254 | + ], |
|
255 | + parts => [ |
|
256 | + Email::MIME->create( |
|
257 | + attributes => { |
|
258 | + content_type => 'text/plain', |
|
259 | + charset => 'UTF-8', |
|
260 | + #encoding => '8bit', |
|
261 | + encoding => 'base64', |
|
262 | + }, |
|
263 | + body => encode( $charset_input, $body ), |
|
264 | + ), |
|
265 | + Email::MIME->create( |
|
266 | + attributes => { |
|
267 | + content_type => $file_type, |
|
268 | + name => encode( 'MIME-Header', $file_name ), |
|
269 | + filename => encode( 'MIME-Header', $file_name ), |
|
270 | + encoding => 'base64', |
|
271 | + disposition => 'attachment', |
|
272 | + }, |
|
273 | + body => $file_body, |
|
274 | + ), |
|
275 | + ], |
|
276 | + ); |
|
277 | + |
|
278 | + return sendmail($email); |
|
279 | +} |
|
280 | + |
|
281 | +sub getHostName |
|
282 | +{ |
|
283 | + my $ip_address = shift || ''; |
|
284 | + my $ret = ''; |
|
285 | + |
|
286 | + my $resolver = Net::DNS::Resolver->new; |
|
287 | + if ( my $ans = $resolver->query( $ip_address ) ){ |
|
288 | + for my $rr ( $ans->answer ){ |
|
289 | + #print $rr->string, "\n"; |
|
290 | + if ( $rr->type eq 'PTR' ){ |
|
291 | + $ret = $rr->ptrdname; |
|
292 | + last; |
|
293 | + } |
|
294 | + } |
|
295 | + } |
|
296 | + |
|
297 | + return $ret; |
|
298 | +} |
|
299 | + |
|
300 | +# EOF |
|
301 | +``` |
|
302 | + |
|
303 | +## config.yaml |
|
304 | +``` |
|
305 | +# MailForm 設定 |
|
306 | +FromAddress: '"メールフォーム" <MailForm@example.com>' |
|
307 | +ToAddress: '"YourAddress" <YourAddress@example.com>' |
|
308 | +MailTitle: "レポート" |
|
309 | +CSSFile: "/take.css" |
|
310 | +``` |
|
311 | + |
|
312 | +# mod_security |
|
313 | +- セッション使わず、クッキーの中にユーザ名と Email がそのまま入っていて、mod_security の crs でエラーになる。 |
|
314 | +- 該当するルール |
|
315 | + - file: modsecurity_crs_41_sql_injection_attacks.conf |
|
316 | + - id: 960024, 981172, 981243, 981245, 981246, 981257 |
|
317 | + |
|
318 | +# リンク |
|
319 | +- [CPAN:Email-Sender](http://search.cpan.org/dist/Email-Sender) |
|
320 | + - [CPAN:Email-Sender/lib/Email/Sender/Manual/QuickStart.pm](http://search.cpan.org/dist/Email-Sender/lib/Email/Sender/Manual/QuickStart.pm) |
|
321 | +- [CPAN:Email-Address](http://search.cpan.org/dist/Email-Address) |
|
322 | +- [CPAN:Email-MIME](http://search.cpan.org/dist/Email-MIME) |
|
323 | +- [CPAN:CGI](http://search.cpan.org/dist/CGI) |
|
324 | + - [CPAN:CGI/lib/CGI.pm](http://search.cpan.org/dist/CGI/lib/CGI.pm) |
|
325 | + - [CPAN:CGI/lib/CGI/Cookie.pm](http://search.cpan.org/dist/CGI/lib/CGI/Cookie.pm) |
|
326 | +- [CPAN:CGI-Session](http://search.cpan.org/dist/CGI-Session) |
|
327 | + - [CPAN:CGI-Session/lib/CGI/Session/Tutorial.pm](http://search.cpan.org/dist/CGI-Session/lib/CGI/Session/Tutorial.pm) |
|
328 | + |
|
329 | +- [モダンPerlの世界へようこそ … 技術評論社](http://gihyo.jp/dev/serial/01/modern-perl) |
|
330 | + - [第20回 Email::Sender:メールを送信する](http://gihyo.jp/dev/serial/01/modern-perl/0020) |
|
331 | + |
|
332 | +- [404 Blog Not Found](http://blog.livedoor.jp/dankogai/) |
|
333 | + - [ドコモもauはとりあえず"da..me."@を受け取れるようにしとくべし](http://blog.livedoor.jp/dankogai/archives/50954045.html) |
|
... | ... | \ No newline at end of file |
Perl/MatchList.md
... | ... | @@ -0,0 +1,79 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- 正規表現によるマッチ結果をリスト化する。 |
|
5 | +- リストコンテキストで /g を付けて評価する。 |
|
6 | + |
|
7 | +# ソース |
|
8 | +- [matchlist.zip](matchlist.zip) |
|
9 | +```perl |
|
10 | +# マッチ結果のリスト化 |
|
11 | +# リストコンテキストで /g を付けて評価する。 |
|
12 | + |
|
13 | +use strict; |
|
14 | +use warnings; |
|
15 | +use utf8; |
|
16 | +use Encode; |
|
17 | + |
|
18 | +#my $charsetConsole = 'UTF-8'; |
|
19 | +my $charsetConsole = 'CP932'; |
|
20 | +my $charsetFile = 'UTF-8'; |
|
21 | + |
|
22 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
23 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
24 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
25 | + |
|
26 | +# 次の文字列を「key=val」として分解する |
|
27 | +# key は空白を含みうる。val は空白を含まない。 |
|
28 | +# 「t u」はマッチしないので無視される |
|
29 | +my $line = "aa = bb cc dd= ee ff gg hh= ii jj kk = ll mm=nn o= p q r= s t u"; |
|
30 | +print "${line}\n\n"; |
|
31 | + |
|
32 | +# ペア単位でリスト化した後、key/valに分解。順序は保存される。 |
|
33 | +foreach my $pair ( $line =~ /[^=]*\S\s*=\s*\S+\s*/g ){ |
|
34 | + my( $key, $val ) = ( $pair =~ /^([^=]*\S)\s*=\s*(\S+)\s*$/ ); |
|
35 | + print "key:'${key}'\tval:'${val}'\n"; |
|
36 | +} |
|
37 | +print "\n"; |
|
38 | + |
|
39 | +# マッチ結果リストをハッシュとして受ける。順序は保存されない。 |
|
40 | +my %pairs = ( $line =~ /([^=]*\S)\s*=\s*(\S+)\s*/g ); |
|
41 | +foreach my $key ( keys( %pairs ) ){ |
|
42 | + print "key:'${key}'\tval:'${pairs{$key}}'\n"; |
|
43 | +} |
|
44 | + |
|
45 | +# EOF |
|
46 | +``` |
|
47 | + |
|
48 | +# 出力結果 |
|
49 | +``` |
|
50 | +aa = bb cc dd= ee ff gg hh= ii jj kk = ll mm=nn o= p q r= s t u |
|
51 | + |
|
52 | +key:'aa' val:'bb' |
|
53 | +key:'cc dd' val:'ee' |
|
54 | +key:'ff gg hh' val:'ii' |
|
55 | +key:'jj kk' val:'ll' |
|
56 | +key:'mm' val:'nn' |
|
57 | +key:'o' val:'p' |
|
58 | +key:'q r' val:'s' |
|
59 | + |
|
60 | +key:'jj kk' val:'ll' |
|
61 | +key:'mm' val:'nn' |
|
62 | +key:'q r' val:'s' |
|
63 | +key:'ff gg hh' val:'ii' |
|
64 | +key:'cc dd' val:'ee' |
|
65 | +key:'aa' val:'bb' |
|
66 | +key:'o' val:'p' |
|
67 | +``` |
|
68 | + |
|
69 | +# リンク |
|
70 | +- [[Perl/ApacheErrorLogFormatter]] |
|
71 | + |
|
72 | +- http://perldoc.jp/ |
|
73 | + - [Perl の正規表現のチュートリアル](http://perldoc.jp/docs/perl/5.14.1/perlretut.pod) |
|
74 | + |
|
75 | +- [Perl programming documentation](http://perldoc.perl.org/) |
|
76 | + - [perlrequick](http://perldoc.perl.org/perlrequick.html) |
|
77 | + |
|
78 | +- [DebugIto's](http://debugitos.main.jp/) |
|
79 | + - [一つの正規表現パターンで複数回マッチ](http://debugitos.main.jp/?Perl/Tips#y2638d73) |
|
... | ... | \ No newline at end of file |
Perl/MySQL-BIT.md
... | ... | @@ -0,0 +1,291 @@ |
1 | +# MySQL BIT型 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- DBI から BIT 型にバインドする際には pack('C*',$x) してからバインドするべし。 |
|
6 | +- BIT は TINYINT として実装されている。 |
|
7 | +- 格納できる数値より大きな値を格納しようとした場合は全ビットが1になった値が格納される。 |
|
8 | + |
|
9 | +## ソース |
|
10 | +- [testBit.zip](testBit.zip) |
|
11 | + |
|
12 | +### testBit.pl |
|
13 | +```perl |
|
14 | +#!/usr/bin/perl |
|
15 | +# testBit.pl |
|
16 | +# MySQL の Bit 型の取り扱いテスト |
|
17 | + |
|
18 | +use strict; |
|
19 | +use warnings; |
|
20 | +use utf8; |
|
21 | +use Encode; |
|
22 | +use YAML::Syck; |
|
23 | +use JSON::Syck; |
|
24 | +use lib qw( /home/Shared/lib/ ); |
|
25 | +use DBIx::NamedParams; |
|
26 | + |
|
27 | +$YAML::Syck::ImplicitUnicode = 1; |
|
28 | +$YAML::Syck::ImplicitTyping = 1; |
|
29 | +$YAML::Syck::Headless = 1; |
|
30 | + |
|
31 | +my $charsetConsole = 'UTF-8'; |
|
32 | +#my $charsetConsole = 'CP932'; |
|
33 | +my $charsetFile = 'UTF-8'; |
|
34 | + |
|
35 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
36 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
37 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
38 | + |
|
39 | +my $config_file = 'config.yaml'; |
|
40 | + |
|
41 | +my $sql_insert = qq{ |
|
42 | + INSERT INTO |
|
43 | + `test_bit` |
|
44 | + ( `packtype`, `value`, `bit1`, `bit4`, `bit8`, `bit12`, `bit16` ) |
|
45 | + VALUES |
|
46 | + ( :packtype-VARCHAR, :value-VARCHAR, :bit1-BIT, :bit4-BIT, :bit8-BIT, :bit12-BIT, :bit16-BIT ); |
|
47 | +}; |
|
48 | +my $sql_select = qq{ |
|
49 | + SELECT `id`, `packtype`, `value`, `bit1`, `bit4`, `bit8`, `bit12`, `bit16` |
|
50 | + FROM `test_bit` |
|
51 | + ORDER BY `id` |
|
52 | +}; |
|
53 | + |
|
54 | +my @input_types = qw( N B C ); |
|
55 | +my @input_values = qw( |
|
56 | + 0 1 10 100 1000 10000 100000000 100000000000 1000000000000 10000000000000000 |
|
57 | + 01 001 0001 00001 000000001 000000000001 0000000000001 00000000000000001 |
|
58 | + 010 0010 00010 000010 0000000010 0000000000010 00000000000010 000000000000000010 |
|
59 | + 2 3 4 5 6 7 8 10 12 15 16 17 255 256 512 513 |
|
60 | +); |
|
61 | + |
|
62 | +my $config = YAML::Syck::LoadFile( $config_file ) |
|
63 | + or die( "$config_file: $!\n" ); |
|
64 | +foreach( keys( %{$config} ) ){ |
|
65 | + $config->{'DSN'} =~ s/_${_}_/$config->{$_}/; |
|
66 | +} |
|
67 | + |
|
68 | +my $dbh = DBI->connect( |
|
69 | + 'DBI:' . $config->{'DSN'}, |
|
70 | + $config->{'User'}, |
|
71 | + $config->{'Password'}, |
|
72 | + $config->{'Options'} |
|
73 | +) or die( "$DBI::errstr\n" ); |
|
74 | + |
|
75 | +my $sth_insert = $dbh->prepare_ex( $sql_insert ) or die( "$DBI::errstr\n" ); |
|
76 | +foreach my $type ( @input_types ){ |
|
77 | + foreach my $value ( @input_values ){ |
|
78 | + my $params = { packtype => $type, value => $value }; |
|
79 | + foreach my $bit ( qw( 1 4 8 12 16 ) ){ |
|
80 | + if ( $type eq 'B' ){ |
|
81 | + $params->{ "bit${bit}" } = pack( "B${bit}", $value ); |
|
82 | + } elsif( $type eq 'C' ){ |
|
83 | + $params->{ "bit${bit}" } = pack( 'C*', int2array( $value ) ); |
|
84 | + } else { |
|
85 | + $params->{ "bit${bit}" } = $value; |
|
86 | + } |
|
87 | + } |
|
88 | + $sth_insert->bind_param_ex( $params ); |
|
89 | + $sth_insert->execute() or die( "$DBI::errstr\n" ); |
|
90 | + } |
|
91 | +} |
|
92 | +$sth_insert->finish; |
|
93 | + |
|
94 | +my $sth_select = $dbh->prepare_ex( $sql_select ) or die( "$DBI::errstr\n" ); |
|
95 | +$sth_select->execute() or die( "$DBI::errstr\n" ); |
|
96 | +my @result = (); |
|
97 | +while( my $array_ref = $sth_select->fetchrow_arrayref ){ |
|
98 | + my @result2 = split( "\n", Dump( $array_ref ) ); |
|
99 | + push( @result, join( "\t", map{ /^\s*-\s*(.*)$/msx; $1; } @result2 ) ); |
|
100 | +} |
|
101 | +$sth_select->finish; |
|
102 | + |
|
103 | +$dbh->disconnect; |
|
104 | + |
|
105 | +print join( "\n", @result ) . "\n"; |
|
106 | + |
|
107 | +exit; |
|
108 | + |
|
109 | +sub int2array |
|
110 | +{ |
|
111 | + my $arg = shift || 0; |
|
112 | + my @ret = (); |
|
113 | + if ( !!$arg ){ |
|
114 | + while( !!$arg ){ |
|
115 | + my $m = $arg & 0xff; |
|
116 | + unshift( @ret, $m ); |
|
117 | + $arg >>= 8; |
|
118 | + } |
|
119 | + } else { |
|
120 | + @ret = ( 0 ); |
|
121 | + } |
|
122 | + return @ret; |
|
123 | +} |
|
124 | + |
|
125 | +# EOF |
|
126 | +``` |
|
127 | + |
|
128 | +## 結果 |
|
129 | + |
|
130 | +### 無変換 |
|
131 | +| id | Type | 値 | bit1 | bit4 | bit8 | bit12 | bit16 | |
|
132 | +| --- | --- | --- | --- | --- | --- | --- | --- | |
|
133 | +| 1 | 'N' | | "\x01" | "\x0F" | | "\00" | "\00" | |
|
134 | +| 2 | 'N' | 1 | "\x01" | "\x0F" | 1 | "\01" | "\01" | |
|
135 | +| 3 | 'N' | 10 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | 10 | |
|
136 | +| 4 | 'N' | 100 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
137 | +| 5 | 'N' | 1000 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
138 | +| 6 | 'N' | 10000 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
139 | +| 7 | 'N' | 100000000 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
140 | +| 8 | 'N' | '100000000000' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
141 | +| 9 | 'N' | '1000000000000' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
142 | +| 10 | 'N' | '10000000000000000' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
143 | +| 11 | 'N' | '01' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | '01' | |
|
144 | +| 12 | 'N' | '001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
145 | +| 13 | 'N' | '0001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
146 | +| 14 | 'N' | '00001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
147 | +| 15 | 'N' | '000000001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
148 | +| 16 | 'N' | '000000000001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
149 | +| 17 | 'N' | '0000000000001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
150 | +| 18 | 'N' | '00000000000000001' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
151 | +| 19 | 'N' | '010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
152 | +| 20 | 'N' | '0010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
153 | +| 21 | 'N' | '00010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
154 | +| 22 | 'N' | '000010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
155 | +| 23 | 'N' | '0000000010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
156 | +| 24 | 'N' | '0000000000010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
157 | +| 25 | 'N' | '00000000000010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
158 | +| 26 | 'N' | '000000000000000010' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
159 | +| 27 | 'N' | 2 | "\x01" | "\x0F" | 2 | "\02" | "\02" | |
|
160 | +| 28 | 'N' | 3 | "\x01" | "\x0F" | 3 | "\03" | "\03" | |
|
161 | +| 29 | 'N' | 4 | "\x01" | "\x0F" | 4 | "\04" | "\04" | |
|
162 | +| 30 | 'N' | 5 | "\x01" | "\x0F" | 5 | "\05" | "\05" | |
|
163 | +| 31 | 'N' | 6 | "\x01" | "\x0F" | 6 | "\06" | "\06" | |
|
164 | +| 32 | 'N' | 7 | "\x01" | "\x0F" | 7 | "\07" | "\07" | |
|
165 | +| 33 | 'N' | 8 | "\x01" | "\x0F" | 8 | "\08" | "\08" | |
|
166 | +| 34 | 'N' | 10 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | 10 | |
|
167 | +| 35 | 'N' | 12 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | 12 | |
|
168 | +| 36 | 'N' | 15 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | 15 | |
|
169 | +| 37 | 'N' | 16 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | 16 | |
|
170 | +| 38 | 'N' | 17 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | 17 | |
|
171 | +| 39 | 'N' | 255 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
172 | +| 40 | 'N' | 256 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
173 | +| 41 | 'N' | 512 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
174 | +| 42 | 'N' | 513 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
175 | + |
|
176 | +### pack('Bn',$x) |
|
177 | +| id | Type | 値 | bit1 | bit4 | bit8 | bit12 | bit16 | |
|
178 | +| --- | --- | --- | --- | --- | --- | --- | --- | |
|
179 | +| 43 | B | | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
180 | +| 44 | B | 1 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
181 | +| 45 | B | 10 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
182 | +| 46 | B | 100 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
183 | +| 47 | B | 1000 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
184 | +| 48 | B | 10000 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
185 | +| 49 | B | 100000000 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
186 | +| 50 | B | '100000000000' | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
187 | +| 51 | B | '1000000000000' | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
188 | +| 52 | B | '10000000000000000' | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
189 | +| 53 | B | '01' | "\0" | "\x0F" | "@" | "\x0F\xFF" | "@\0" | |
|
190 | +| 54 | B | '001' | "\0" | "\x0F" | " " | "\x0F\xFF" | " \0" | |
|
191 | +| 55 | B | '0001' | "\0" | "\x0F" | "\x10" | "\x0F\xFF" | "\x10\0" | |
|
192 | +| 56 | B | '00001' | "\0" | "\0" | "\b" | "\b\0" | "\b\0" | |
|
193 | +| 57 | B | '000000001' | "\0" | "\0" | "\0" | "\0\x80" | "\0\x80" | |
|
194 | +| 58 | B | '000000000001' | "\0" | "\0" | "\0" | "\0\x10" | "\0\x10" | |
|
195 | +| 59 | B | '0000000000001' | "\0" | "\0" | "\0" | "\0\0" | "\0\b" | |
|
196 | +| 60 | B | '00000000000000001' | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
197 | +| 61 | B | '010' | "\0" | "\x0F" | "@" | "\x0F\xFF" | "@\0" | |
|
198 | +| 62 | B | '0010' | "\0" | "\x0F" | " " | "\x0F\xFF" | " \0" | |
|
199 | +| 63 | B | '00010' | "\0" | "\x0F" | "\x10" | "\x0F\xFF" | "\x10\0" | |
|
200 | +| 64 | B | '000010' | "\0" | "\0" | "\b" | "\b\0" | "\b\0" | |
|
201 | +| 65 | B | '0000000010' | "\0" | "\0" | "\0" | "\0\x80" | "\0\x80" | |
|
202 | +| 66 | B | '0000000000010' | "\0" | "\0" | "\0" | "\0\x10" | "\0\x10" | |
|
203 | +| 67 | B | '00000000000010' | "\0" | "\0" | "\0" | "\0\0" | "\0\b" | |
|
204 | +| 68 | B | '000000000000000010' | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
205 | +| 69 | B | 2 | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
206 | +| 70 | B | 3 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
207 | +| 71 | B | 4 | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
208 | +| 72 | B | 5 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
209 | +| 73 | B | 6 | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
210 | +| 74 | B | 7 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
211 | +| 75 | B | 8 | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
212 | +| 76 | B | 10 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
213 | +| 77 | B | 12 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
214 | +| 78 | B | 15 | "\x01" | "\x0F" | "\xC0" | "\x0F\xFF" | "\xC0\0" | |
|
215 | +| 79 | B | 16 | "\x01" | "\x0F" | "\x80" | "\x0F\xFF" | "\x80\0" | |
|
216 | +| 80 | B | 17 | "\x01" | "\x0F" | "\xC0" | "\x0F\xFF" | "\xC0\0" | |
|
217 | +| 81 | B | 255 | "\0" | "\x0F" | "`" | "\x0F\xFF" | "`\0" | |
|
218 | +| 82 | B | 256 | "\0" | "\x0F" | "@" | "\x0F\xFF" | "@\0" | |
|
219 | +| 83 | B | 512 | "\x01" | "\x0F" | "\xC0" | "\x0F\xFF" | "\xC0\0" | |
|
220 | +| 84 | B | 513 | "\x01" | "\x0F" | "\xE0" | "\x0F\xFF" | "\xE0\0" | |
|
221 | + |
|
222 | +### pack('C*',$x) |
|
223 | +| id | Type | 値 | bit1 | bit4 | bit8 | bit12 | bit16 | |
|
224 | +| --- | --- | --- | --- | --- | --- | --- | --- | |
|
225 | +| 85 | C | | "\0" | "\0" | "\0" | "\0\0" | "\0\0" | |
|
226 | +| 86 | C | 1 | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
227 | +| 87 | C | 10 | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
228 | +| 88 | C | 100 | "\x01" | "\x0F" | d | "\0d" | "\0d" | |
|
229 | +| 89 | C | 1000 | "\x01" | "\x0F" | "\xFF" | "\x03\xE8" | "\x03\xE8" | |
|
230 | +| 90 | C | 10000 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "'\x10" | |
|
231 | +| 91 | C | 100000000 | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
232 | +| 92 | C | '100000000000' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
233 | +| 93 | C | '1000000000000' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
234 | +| 94 | C | '10000000000000000' | "\x01" | "\x0F" | "\xFF" | "\x0F\xFF" | "\xFF\xFF" | |
|
235 | +| 95 | C | '01' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
236 | +| 96 | C | '001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
237 | +| 97 | C | '0001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
238 | +| 98 | C | '00001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
239 | +| 99 | C | '000000001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
240 | +| 100 | C | '000000000001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
241 | +| 101 | C | '0000000000001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
242 | +| 102 | C | '00000000000000001' | "\x01" | "\x01" | "\x01" | "\0\x01" | "\0\x01" | |
|
243 | +| 103 | C | '010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
244 | +| 104 | C | '0010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
245 | +| 105 | C | '00010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
246 | +| 106 | C | '000010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
247 | +| 107 | C | '0000000010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
248 | +| 108 | C | '0000000000010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
249 | +| 109 | C | '00000000000010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
250 | +| 110 | C | '000000000000000010' | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
251 | +| 111 | C | 2 | "\x01" | "\x02" | "\x02" | "\0\x02" | "\0\x02" | |
|
252 | +| 112 | C | 3 | "\x01" | "\x03" | "\x03" | "\0\x03" | "\0\x03" | |
|
253 | +| 113 | C | 4 | "\x01" | "\x04" | "\x04" | "\0\x04" | "\0\x04" | |
|
254 | +| 114 | C | 5 | "\x01" | "\x05" | "\x05" | "\0\x05" | "\0\x05" | |
|
255 | +| 115 | C | 6 | "\x01" | "\x06" | "\x06" | "\0\x06" | "\0\x06" | |
|
256 | +| 116 | C | 7 | "\x01" | "\a" | "\a" | "\0\a" | "\0\a" | |
|
257 | +| 117 | C | 8 | "\x01" | "\b" | "\b" | "\0\b" | "\0\b" | |
|
258 | +| 118 | C | 10 | "\x01" | "\n" | "\n" | "\0\n" | "\0\n" | |
|
259 | +| 119 | C | 12 | "\x01" | "\f" | "\f" | "\0\f" | "\0\f" | |
|
260 | +| 120 | C | 15 | "\x01" | "\x0F" | "\x0F" | "\0\x0F" | "\0\x0F" | |
|
261 | +| 121 | C | 16 | "\x01" | "\x0F" | "\x10" | "\0\x10" | "\0\x10" | |
|
262 | +| 122 | C | 17 | "\x01" | "\x0F" | "\x11" | "\0\x11" | "\0\x11" | |
|
263 | +| 123 | C | 255 | "\x01" | "\x0F" | "\xFF" | "\0\xFF" | "\0\xFF" | |
|
264 | +| 124 | C | 256 | "\x01" | "\x0F" | "\xFF" | "\x01\0" | "\x01\0" | |
|
265 | +| 125 | C | 512 | "\x01" | "\x0F" | "\xFF" | "\x02\0" | "\x02\0" | |
|
266 | +| 126 | C | 513 | "\x01" | "\x0F" | "\xFF" | "\x02\x01" | "\x02\x01" | |
|
267 | + |
|
268 | +## テーブル |
|
269 | +```sql |
|
270 | +CREATE TABLE IF NOT EXISTS `test_bit` ( |
|
271 | + `id` int(11) NOT NULL AUTO_INCREMENT, |
|
272 | + `packtype` varchar(1) DEFAULT NULL, |
|
273 | + `value` varchar(20) DEFAULT NULL, |
|
274 | + `bit1` bit(1) DEFAULT NULL, |
|
275 | + `bit4` bit(4) DEFAULT NULL, |
|
276 | + `bit8` bit(8) DEFAULT NULL, |
|
277 | + `bit12` bit(12) DEFAULT NULL, |
|
278 | + `bit16` bit(16) DEFAULT NULL, |
|
279 | + PRIMARY KEY (`id`) |
|
280 | +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; |
|
281 | + |
|
282 | +DELETE FROM `test_bit` WHERE 1; |
|
283 | +ALTER TABLE `test_bit` AUTO_INCREMENT = 1; |
|
284 | +``` |
|
285 | + |
|
286 | +## リンク |
|
287 | +- Perl/packBit |
|
288 | +- MySQL |
|
289 | + |
|
290 | +- [PerlMonks - The Monastery Gates](http://www.perlmonks.org/) |
|
291 | + - [Handle MySQL BIT data type in Perl](http://www.perlmonks.org/?node_id=504470) |
|
... | ... | \ No newline at end of file |
Perl/NetWatcher.md
... | ... | @@ -0,0 +1,547 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- ネットワーク上のサーバの ping による死活監視および WakeOnLan によるリモート起動を行う。 |
|
5 | +- 監視するのはスクリプトを呼び出した時1回だけで履歴は取らない。 |
|
6 | +- 再度監視したい場合はタイトルがリンクになっているので、そこをクリックする。 |
|
7 | +- Windows/IIS 版を追加。(2012/03/28) |
|
8 | +- [CPAN:Doxygen-Filter-Perl](http://search.cpan.org/dist/Doxygen-Filter-Perl) 用タグの書き方が間違っていたのを訂正。(2012/03/28) |
|
9 | +- Linux/Apache 版で<form>が閉じていなかったのを修正。(2012/03/28) |
|
10 | +- 関数内で print するのを止め、HTML文字列を返すように変更。(2012/03/29) |
|
11 | +- NIC が2枚以上ある場合に対応。「/」で連結して書く。(2012/05/30) |
|
12 | +- Name の先頭に「#」が付いている行はコメントとして無視される。(2012/06/04) |
|
13 | + |
|
14 | +# ソース |
|
15 | +- [NetWatcher.zip](NetWatcher.zip) |
|
16 | + |
|
17 | +## index.cgi (Linux/Apache) |
|
18 | +```perl |
|
19 | +#!/usr/bin/perl |
|
20 | +## @mainpage NetWatcher |
|
21 | +# サーバの監視およびリモート起動 |
|
22 | + |
|
23 | +use strict; |
|
24 | +use warnings; |
|
25 | +use utf8; |
|
26 | +use Encode; |
|
27 | +use YAML::Syck; |
|
28 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
29 | +use Text::xSV::Slurp qw( xsv_slurp ); |
|
30 | +use Net::Ping::External qw( ping ); |
|
31 | +use Net::Wake; |
|
32 | +use Parallel::ForkManager; |
|
33 | +use IPC::Shareable; |
|
34 | + |
|
35 | +$YAML::Syck::ImplicitUnicode = 1; |
|
36 | + |
|
37 | +#my $charsetConsole = 'CP932'; |
|
38 | +my $charsetConsole = 'UTF-8'; |
|
39 | +my $charsetFile = 'UTF-8'; |
|
40 | + |
|
41 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
42 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
43 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
44 | + |
|
45 | +my $cginame = 'NetWatcher'; ##< CGI名 |
|
46 | +my $cookiename = 'NWCookie'; ##< 現在は使用していない |
|
47 | +my $configfile = './conf/config.txt'; ##< 設定ファイル |
|
48 | +my $csvoption = { sep_char => "\t" }; ##< 設定ファイルを読み込むためのオプション |
|
49 | +my $maxchildren = 10; ##< 子プロセスの最大数 |
|
50 | +my $markignore = '#'; ##< 行頭がこの文字列で始まっている行は無視する。 |
|
51 | + |
|
52 | +my @Targets = readXSV( $configfile, $csvoption ); |
|
53 | +my %Targets = map{ $_->{'Name'} => $_; } @Targets; |
|
54 | + |
|
55 | +#print Dump( \%Targets ) . "\n"; |
|
56 | +#exit; |
|
57 | + |
|
58 | +my %results = pingTargets( \@Targets ); |
|
59 | + |
|
60 | +my $q = new CGI; |
|
61 | +$q->charset( $charsetFile ); |
|
62 | +my $scripturl = $q->url( ); |
|
63 | + |
|
64 | +my @paramnames = $q->param(); |
|
65 | + |
|
66 | +printHeader(); |
|
67 | + |
|
68 | +if ( @paramnames ){ |
|
69 | + action(); |
|
70 | +} |
|
71 | +printForm(); |
|
72 | + |
|
73 | +printFooter(); |
|
74 | + |
|
75 | +exit; |
|
76 | + |
|
77 | +## @function readXSV( $fname, %$opt ) |
|
78 | +# CSV(TSV)ファイルを読み込んでヘッダ行をキーとしたハッシュの配列を返す。 |
|
79 | +# @param fname [in] ファイル名 |
|
80 | +# @param opt [in] Text::CSV_XS に渡されるオプション |
|
81 | +# @return CSVを配列化したもの |
|
82 | +sub readXSV |
|
83 | +{ |
|
84 | + my( $fname, $opt ) = @_; |
|
85 | + $opt = { binary => 1, %{$opt} }; |
|
86 | + open( my $fhin, "<:encoding($charsetFile)", encode( $charsetConsole, $fname ) ) |
|
87 | + or die( "$fname: $!" ); |
|
88 | + my @body = <$fhin>; |
|
89 | + close( $fhin ); |
|
90 | + my $ret = xsv_slurp( |
|
91 | + string => join( "", @body ), |
|
92 | + text_csv => $opt, |
|
93 | + ); |
|
94 | + return ( ref( $ret ) eq 'ARRAY' ) |
|
95 | + ? @{ $ret } |
|
96 | + : $ret ; |
|
97 | +} |
|
98 | + |
|
99 | +## @function pingTargets( @$targets_ref ) |
|
100 | +# ターゲット情報に従い、各ターゲット宛に ping を打ち、結果をハッシュにして返す。 |
|
101 | +# @param targets_ref [in] ターゲット情報の配列のリファレンス |
|
102 | +# @return ping 結果のハッシュ |
|
103 | +sub pingTargets |
|
104 | +{ |
|
105 | + my( $targets_ref ) = @_; |
|
106 | + |
|
107 | + my $handle = tie my %results, 'IPC::Shareable', undef, { destroy => 1 }; |
|
108 | + %results = (); |
|
109 | + |
|
110 | + my $pm = Parallel::ForkManager->new( $maxchildren ); |
|
111 | + |
|
112 | +# $pm->run_on_start( |
|
113 | +# sub { |
|
114 | +# my( $pid, $ident ) = @_; |
|
115 | +# print "** $ident started, pid: $pid\n"; |
|
116 | +# } |
|
117 | +# ); |
|
118 | + |
|
119 | + foreach my $target ( @{$targets_ref} ){ |
|
120 | + my $name = $target->{ 'Name' } || ''; |
|
121 | + if ( substr( $name, 0, length($markignore) ) eq $markignore ){ |
|
122 | + next; |
|
123 | + } |
|
124 | + my $ip = $target->{ 'IP' } || ''; |
|
125 | + $pm->start( $name ) and next; |
|
126 | + my $status = ping( host => $ip, timeout => 1 ); |
|
127 | + $handle->shlock; |
|
128 | + $results{ $name } = $status; |
|
129 | + $handle->shunlock; |
|
130 | + $pm->finish( $name ); |
|
131 | + } |
|
132 | + $pm->wait_all_children; |
|
133 | + |
|
134 | + my %ret = %results; |
|
135 | + $handle->remove(); |
|
136 | + |
|
137 | + return %ret; |
|
138 | +} |
|
139 | + |
|
140 | +## @function printHeader() |
|
141 | +# HTTP ヘッダおよび HTML ヘッダを出力する。 |
|
142 | +sub printHeader |
|
143 | +{ |
|
144 | + my $cookieval = decode( 'utf8', |
|
145 | + $q->cookie( encode( 'utf8', $cookiename ) ) || '' |
|
146 | + ); |
|
147 | +# $cookieval .= 'あ'; |
|
148 | + my $cookie = $q->cookie( |
|
149 | + '-name' => encode( 'utf8', $cookiename ), |
|
150 | + '-value' => encode( 'utf8', $cookieval ), |
|
151 | + ); |
|
152 | + print $q->header( '-cookie' => [ $cookie ] ); |
|
153 | + print $q->start_html( |
|
154 | + '-title' => $cginame, |
|
155 | + '-lang' => 'ja-JP', |
|
156 | + '-head' => [ |
|
157 | + $q->meta( { '-http_equiv' => 'Content-style-type', '-content' => 'text/css' } ), |
|
158 | + $q->meta( { '-http_equiv' => 'Content-script-type', '-content' => 'text/javascript' } ), |
|
159 | + ], |
|
160 | + '-style' => [ { 'src' => 'NetWatcher.css' }, ], |
|
161 | + ); |
|
162 | + print $q->h1( $q->a( { -href => $scripturl }, $cginame ) ); |
|
163 | +} |
|
164 | + |
|
165 | +## @function printFooter() |
|
166 | +# HTML フッタを出力する。 |
|
167 | +sub printFooter |
|
168 | +{ |
|
169 | + print $q->end_html . "\n"; |
|
170 | +} |
|
171 | + |
|
172 | +## @function action() |
|
173 | +# フォームから送信されたコマンドを処理する。 |
|
174 | +sub action |
|
175 | +{ |
|
176 | + print $q->h2( 'Command' ); |
|
177 | + print $q->start_table( { '-summary' => 'Servers', '-border' => 1 } ); |
|
178 | + foreach my $key ( @paramnames ){ |
|
179 | + print $q->Tr( |
|
180 | + { -class => 'even' }, |
|
181 | + $q->th( { -class => 'title' }, $key ), $q->td( $q->param( $key ) ) |
|
182 | + ); |
|
183 | + } |
|
184 | + print $q->end_table(); |
|
185 | + my $target = $q->param( 'Wake' ) || ''; |
|
186 | + if ( $target && $Targets{$target} ){ |
|
187 | + foreach my $mac ( split( /\//, $Targets{$target}{'MAC'} ) ){ |
|
188 | + Net::Wake::by_udp( undef, $mac ); |
|
189 | + } |
|
190 | + } |
|
191 | +} |
|
192 | + |
|
193 | +## @function printForm() |
|
194 | +# フォームを出力する。 |
|
195 | +sub printForm |
|
196 | +{ |
|
197 | + print $q->h2( 'ステータス' ); |
|
198 | + print $q->start_form( |
|
199 | + '-action' => $scripturl, |
|
200 | + '-enctype' => ( 'multipart/form-data' ), |
|
201 | + ); |
|
202 | + print $q->start_table( { '-summary' => 'Statuses', '-border' => 1 } ); |
|
203 | + print $q->Tr( $q->th( { -class => 'title' }, [ 'Name', 'Type', 'IP', 'Status', 'Wake', '備考' ] ) ); |
|
204 | + for( my $i=0; $i<@Targets; ++$i ){ |
|
205 | + my $name = $Targets[ $i ]{'Name'} || ''; |
|
206 | + if ( substr( $name, 0, length($markignore) ) eq $markignore ){ |
|
207 | + next; |
|
208 | + } |
|
209 | + my $type = $Targets[ $i ]{'Type'} || ''; |
|
210 | + my $ip = $Targets[ $i ]{'IP'} || ''; |
|
211 | + my $status = ( $results{ $name } ) |
|
212 | + ? $q->td( { -class => 'state_up' }, 'Up' ) |
|
213 | + : $q->td( { -class => 'state_down' }, 'Down' ); |
|
214 | + my $comment = $Targets[ $i ]{'Comment'} || ''; |
|
215 | + print $q->Tr( |
|
216 | + { -class => ( $i % 2 ) ? 'odd' : 'even' }, |
|
217 | + $q->th( $name ), |
|
218 | + $q->td( [ $type, $ip ] ), |
|
219 | + $status, |
|
220 | + $q->td( [ $q->submit( -name=>'Wake', -value=>$name ), $comment, ] ), |
|
221 | + ); |
|
222 | + } |
|
223 | + print $q->end_table(); |
|
224 | + $q->end_form; |
|
225 | +} |
|
226 | + |
|
227 | +# EOF |
|
228 | +``` |
|
229 | + |
|
230 | +## index_IIS.cgi (Windows/IIS) |
|
231 | +```perl |
|
232 | +#!/usr/bin/perl |
|
233 | +# NetWatcher (IIS用) |
|
234 | +# サーバの監視およびリモート起動 |
|
235 | + |
|
236 | +use strict; |
|
237 | +use warnings; |
|
238 | +use utf8; |
|
239 | +use Encode; |
|
240 | +use YAML::Syck; |
|
241 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
242 | +use Text::xSV::Slurp qw( xsv_slurp ); |
|
243 | +use Net::Ping::External qw( ping ); |
|
244 | +use Net::Wake; |
|
245 | +use threads; |
|
246 | +use threads::shared; |
|
247 | + |
|
248 | +$YAML::Syck::ImplicitUnicode = 1; |
|
249 | + |
|
250 | +#my $charsetConsole = 'CP932'; |
|
251 | +my $charsetConsole = 'UTF-8'; |
|
252 | +my $charsetFile = 'UTF-8'; |
|
253 | + |
|
254 | +# Encode モジュールは Thread Safe ではない。 |
|
255 | +# http://search.cpan.org/dist/Encode/encoding.pm |
|
256 | +#binmode( STDIN, ":encoding($charsetConsole)" ); |
|
257 | +#binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
258 | +#binmode( STDERR, ":encoding($charsetConsole)" ); |
|
259 | + |
|
260 | +my $encoder = find_encoding( $charsetConsole ); |
|
261 | + |
|
262 | +my $cginame = 'NetWatcher'; |
|
263 | +my $cookiename = 'NWCookie'; ##< 現在は使用していない |
|
264 | +my $configfile = './conf/config.txt'; |
|
265 | +my $csvoption = { sep_char => "\t" }; |
|
266 | +my $markignore = '#'; ##< 行頭がこの文字列で始まっている行は無視する。 |
|
267 | + |
|
268 | +my @Targets = readXSV( $configfile, $csvoption ); |
|
269 | +my %Targets = map{ $_->{'Name'} => $_; } @Targets; |
|
270 | + |
|
271 | +#print $encoder->encode( Dump( \%Targets ) . "\n" ); |
|
272 | +#exit; |
|
273 | + |
|
274 | +my %results = pingTargets( \@Targets ); |
|
275 | + |
|
276 | +my $q = new CGI; |
|
277 | +$q->charset( $charsetConsole ); |
|
278 | +my $scripturl = $q->url( -path_info=>1 ); |
|
279 | + |
|
280 | +my @paramnames = $q->param(); |
|
281 | + |
|
282 | +printHeader(); |
|
283 | + |
|
284 | +if ( @paramnames ){ |
|
285 | + action(); |
|
286 | +} |
|
287 | +printForm(); |
|
288 | + |
|
289 | +printFooter(); |
|
290 | + |
|
291 | +exit; |
|
292 | + |
|
293 | +## @function readXSV( $fname, %$opt ) |
|
294 | +# CSV(TSV)ファイルを読み込んでヘッダ行をキーとしたハッシュの配列を返す。 |
|
295 | +# @param fname [in] ファイル名 |
|
296 | +# @param opt [in] Text::CSV_XS に渡されるオプション |
|
297 | +# @return CSVを配列化したもの |
|
298 | +sub readXSV |
|
299 | +{ |
|
300 | + my( $fname, $opt ) = @_; |
|
301 | + $opt = { binary => 1, %{$opt} }; |
|
302 | + open( my $fhin, "<:encoding($charsetFile)", encode( $charsetConsole, $fname ) ) |
|
303 | + or die( "$fname: $!" ); |
|
304 | + my @body = <$fhin>; |
|
305 | + close( $fhin ); |
|
306 | + my $ret = xsv_slurp( |
|
307 | + string => join( "", @body ), |
|
308 | + text_csv => $opt, |
|
309 | + ); |
|
310 | + return ( ref( $ret ) eq 'ARRAY' ) |
|
311 | + ? @{ $ret } |
|
312 | + : $ret ; |
|
313 | +} |
|
314 | + |
|
315 | +## @function pingTargets( @%targetsref ) |
|
316 | +# ターゲット情報に従い、各ターゲット宛に ping を打ち、結果をハッシュにして返す。 |
|
317 | +# @param targets [in] ターゲット情報の配列 |
|
318 | +# @return ping 結果のハッシュ |
|
319 | +sub pingTargets |
|
320 | +{ |
|
321 | + my( $targets_ref ) = @_; |
|
322 | + |
|
323 | + my %results; |
|
324 | + my %threads; |
|
325 | + foreach my $target ( @{$targets_ref} ) { |
|
326 | + my $name = $target->{ 'Name' } || ''; |
|
327 | + if ( substr( $name, 0, length($markignore) ) eq $markignore ){ |
|
328 | + next; |
|
329 | + } |
|
330 | + my $ip = $target->{ 'IP' } || ''; |
|
331 | + $threads{ $name } = threads->new( |
|
332 | + sub { |
|
333 | + my( $ip ) = @_; |
|
334 | + return ping( host => $ip, timeout => 1 ); |
|
335 | + }, |
|
336 | + $ip |
|
337 | + ); |
|
338 | + } |
|
339 | + foreach my $t ( keys( %threads ) ){ |
|
340 | + $results{ $t } = $threads{ $t }->join(); |
|
341 | + } |
|
342 | + |
|
343 | + return %results; |
|
344 | +} |
|
345 | + |
|
346 | +## @function printHeader() |
|
347 | +# HTTP ヘッダおよび HTML ヘッダを出力する。 |
|
348 | +sub printHeader |
|
349 | +{ |
|
350 | + if ( defined( $ENV{PERLXS} ) && $ENV{PERLXS} eq 'PerlIS' ){ |
|
351 | + print $encoder->encode( "HTTP/1.0 200 OK\n" ); |
|
352 | + } |
|
353 | + |
|
354 | + my $cookieval = decode( 'utf8', |
|
355 | + $q->cookie( encode( 'utf8', $cookiename ) ) || '' |
|
356 | + ); |
|
357 | +# $cookieval .= 'あ'; |
|
358 | + my $cookie = $q->cookie( |
|
359 | + '-name' => encode( 'utf8', $cookiename ), |
|
360 | + '-value' => encode( 'utf8', $cookieval ), |
|
361 | + ); |
|
362 | + print $encoder->encode( $q->header( '-cookie' => [ $cookie ] ) ); |
|
363 | + print $encoder->encode( $q->start_html( |
|
364 | + '-title' => $cginame, |
|
365 | + '-lang' => 'ja-JP', |
|
366 | + '-head' => [ |
|
367 | + $q->meta( { '-http_equiv' => 'Content-style-type', '-content' => 'text/css' } ), |
|
368 | + $q->meta( { '-http_equiv' => 'Content-script-type', '-content' => 'text/javascript' } ), |
|
369 | + ], |
|
370 | + '-style' => [ { 'src' => 'NetWatcher.css' }, ], |
|
371 | + ) ); |
|
372 | + print $encoder->encode( $q->h1( $q->a( { -href => $scripturl }, $cginame ) ) ); |
|
373 | +} |
|
374 | + |
|
375 | +## @function printFooter() |
|
376 | +# HTML フッタを出力する。 |
|
377 | +sub printFooter |
|
378 | +{ |
|
379 | + print $encoder->encode( $q->end_html . "\n" ); |
|
380 | +} |
|
381 | + |
|
382 | +## @function action() |
|
383 | +# フォームから送信されたコマンドを処理する。 |
|
384 | +sub action |
|
385 | +{ |
|
386 | + print $encoder->encode( $q->h2( 'Command' ) ); |
|
387 | + print $encoder->encode( $q->start_table( { '-summary' => 'Servers', '-border' => 1 } ) ); |
|
388 | + foreach my $key ( @paramnames ){ |
|
389 | + print $encoder->encode( $q->Tr( |
|
390 | + { -class => 'even' }, |
|
391 | + $q->th( { -class => 'title' }, $key ), $q->td( $q->param( $key ) ) |
|
392 | + ) ); |
|
393 | + } |
|
394 | + print $encoder->encode( $q->end_table() ); |
|
395 | + my $target = $q->param( 'Wake' ) || ''; |
|
396 | + if ( $target && $Targets{$target} ){ |
|
397 | + foreach my $mac ( split( /\//, $Targets{$target}{'MAC'} ) ){ |
|
398 | + Net::Wake::by_udp( undef, $mac ); |
|
399 | + } |
|
400 | + } |
|
401 | +} |
|
402 | + |
|
403 | +## @function printForm() |
|
404 | +# フォームを出力する。 |
|
405 | +sub printForm |
|
406 | +{ |
|
407 | + print $encoder->encode( $q->h2( 'ステータス' ) ); |
|
408 | + print $encoder->encode( $q->start_form( |
|
409 | + '-action' => $scripturl, |
|
410 | + '-enctype' => ( 'multipart/form-data' ), |
|
411 | + ) ); |
|
412 | + print $encoder->encode( $q->start_table( { '-summary' => 'Statuses', '-border' => 1 } ) ); |
|
413 | + print $encoder->encode( $q->Tr( $q->th( { -class => 'title' }, [ 'Name', 'Type', 'IP', 'Status', 'Wake', '備考' ] ) ) ); |
|
414 | + for( my $i=0; $i<@Targets; ++$i ){ |
|
415 | + my $name = $Targets[ $i ]{'Name'} || ''; |
|
416 | + if ( substr( $name, 0, length($markignore) ) eq $markignore ){ |
|
417 | + next; |
|
418 | + } |
|
419 | + my $type = $Targets[ $i ]{'Type'} || ''; |
|
420 | + my $ip = $Targets[ $i ]{'IP'} || ''; |
|
421 | + my $status = ( $results{ $name } ) |
|
422 | + ? $q->td( { -class => 'state_up' }, 'Up' ) |
|
423 | + : $q->td( { -class => 'state_down' }, 'Down' ); |
|
424 | + my $comment = $Targets[ $i ]{'Comment'} || ''; |
|
425 | + print $encoder->encode( $q->Tr( |
|
426 | + { -class => ( $i % 2 ) ? 'odd' : 'even' }, |
|
427 | + $q->th( $name ), |
|
428 | + $q->td( [ $type, $ip ] ), |
|
429 | + $status, |
|
430 | + $q->td( [ $q->submit( -name=>'Wake', -value=>$name ), $comment, ] ), |
|
431 | + ) ); |
|
432 | + } |
|
433 | + print $encoder->encode( $q->end_table() ); |
|
434 | + print $encoder->encode( $q->end_form() ); |
|
435 | +} |
|
436 | + |
|
437 | +# EOF |
|
438 | +``` |
|
439 | + |
|
440 | +## config.txt |
|
441 | +- サーバ情報設定TSVファイル。 |
|
442 | +- MAC は WakeOnLan のパケットを送信する NIC の MAC アドレス。 |
|
443 | +- NIC が2枚以上ある場合は、「/」で連結して書く。 |
|
444 | +- Name の先頭に「#」が付いている行はコメントとして無視される。 |
|
445 | +``` |
|
446 | +"Name" "Type" "IP" "MAC" "Comment" |
|
447 | +"Srv01" "Win2003" "192.168.0.10" "XX:XX:XX:XX:XX:XX" "Web Hosting" |
|
448 | +"Srv02" "CentOS6" "192.168.0.11" "XX:XX:XX:XX:XX:XX/XX:XX:XX:XX:XX:XX" "Mail, MySQL" |
|
449 | +"#Srv03" "Win2008R2" "192.168.0.12" "XX:XX:XX:XX:XX:XX" "Streaming" |
|
450 | +"Srv04" "MacOSX 10.6" "192.168.0.13" "XX:XX:XX:XX:XX:XX" "FileSrv" |
|
451 | +``` |
|
452 | + |
|
453 | +## NetWatcher.conf |
|
454 | +- Apache 用設定ファイル。 |
|
455 | +- .htaccess でも代用可能。 |
|
456 | +```apache |
|
457 | +<Directory "/var/www/html/NetWatcher"> |
|
458 | + Options ExecCGI Indexes |
|
459 | + DirectoryIndex index.cgi |
|
460 | + Order allow,deny |
|
461 | + Allow from 127.0.0.1 |
|
462 | + Allow from 192.168.0.0/24 |
|
463 | + Allow from 10.8.0.0/24 |
|
464 | +</Directory> |
|
465 | + |
|
466 | +<Directory "/var/www/html/NetWatcher/conf"> |
|
467 | + Options None |
|
468 | + Order allow,deny |
|
469 | +</Directory> |
|
470 | +``` |
|
471 | + |
|
472 | +# システム設定 |
|
473 | + |
|
474 | +## パッケージ追加 |
|
475 | +- EPEL, RPMForge リポジトリを追加しておくこと。<br /> |
|
476 | +[[リポジトリ追加|Linux/Install/CentOS6#Repository]] |
|
477 | +``` |
|
478 | +# yum install perl-Net-Ping-External perl-Parallel-ForkManager perl-IPC-Shareable |
|
479 | +``` |
|
480 | + |
|
481 | +## SELinux設定 |
|
482 | +- audit.log を元にポリシーを作成しインストールする。<br /> |
|
483 | +[[ログ分析|Linux/SELinux#AnalyseLog]] |
|
484 | +``` |
|
485 | +# semodule -d mypol |
|
486 | +# setenforce 0 |
|
487 | +# service auditd rotate |
|
488 | +(NetWatcher実行) |
|
489 | +# setenforce 1 |
|
490 | +# grep "index.cgi\|ping" /var/log/audit/audit.log | audit2allow -M mypol_NetWatcher |
|
491 | +# semodule -i mypol_NetWatcher.pp |
|
492 | +``` |
|
493 | +- mypol_NetWatcher.te<br /> |
|
494 | +こんなポリシーができてるはず。 |
|
495 | +``` |
|
496 | +module mypol_NetWatcher 1.0; |
|
497 | + |
|
498 | +require { |
|
499 | + type httpd_sys_script_t; |
|
500 | + type tmpfs_t; |
|
501 | + class capability { setuid net_raw }; |
|
502 | + class sem { unix_read write unix_write read destroy create }; |
|
503 | + class shm { write associate read create unix_read getattr unix_write destroy }; |
|
504 | + class file { read write }; |
|
505 | + class rawip_socket { write getopt create read setopt }; |
|
506 | +} |
|
507 | + |
|
508 | +#============= httpd_sys_script_t ============== |
|
509 | +allow httpd_sys_script_t self:capability { setuid net_raw }; |
|
510 | +allow httpd_sys_script_t self:rawip_socket { write getopt create read setopt }; |
|
511 | +allow httpd_sys_script_t self:sem { unix_read write unix_write read destroy create }; |
|
512 | +allow httpd_sys_script_t self:shm { unix_read associate read create write getattr unix_write destroy }; |
|
513 | +allow httpd_sys_script_t tmpfs_t:file { read write }; |
|
514 | +``` |
|
515 | + |
|
516 | +- IIS の場合は、ping.exe の「プロパティ - セキュリティ」を開き、「インターネットゲストアカウント(IUSR_<マシン名>)」に「読み取りと実行」権限を付加する。 |
|
517 | + - [[PRB] [IIS 6.0] 外部アプリケーションを呼び出す CGI コードが失敗する](http://support.microsoft.com/kb/311481/) |
|
518 | + |
|
519 | +# リンク |
|
520 | +- [[Perl/CGI.pm]] |
|
521 | +- [[Perl/readXSV]] |
|
522 | + |
|
523 | +- [CPAN:Net-Ping-External](http://search.cpan.org/dist/Net-Ping-External) |
|
524 | +- [CPAN:Net-Arping](http://search.cpan.org/dist/Net-Arping) |
|
525 | +- [CPAN:Net-Wake](http://search.cpan.org/dist/Net-Wake) |
|
526 | +- [CPAN:Parallel-ForkManager](http://search.cpan.org/dist/Parallel-ForkManager) |
|
527 | +- [CPAN:IPC-Shareable](http://search.cpan.org/dist/IPC-Shareable) |
|
528 | +- [CPAN:threads](http://search.cpan.org/dist/threads) |
|
529 | +- [CPAN:threads-shared](http://search.cpan.org/dist/threads-shared) |
|
530 | +- [CPAN:Encode](http://search.cpan.org/dist/Encode) |
|
531 | + - [CPAN:Encode/encoding.pm](http://search.cpan.org/dist/Encode/encoding.pm)<br /> |
|
532 | +use encoding ... is not thread-safe. |
|
533 | + |
|
534 | +- [(Obsolete) Parallel::ForkManager + IPC::Shareable で複数のプロセスで変数を共有する - Yet Another Hackadelic](http://d.hatena.ne.jp/ZIGOROu/20090112/1231756261) |
|
535 | +- [パターン青の集い: memo::Perlによる複数並列処理プログラム](http://todayd308.blogspot.com/2009/10/memoperl.html) |
|
536 | + |
|
537 | +- [Forkが気になりつつthread - ito.tetsunosuke/notebook](http://d.hatena.ne.jp/kidd-number5/20070328/1175065357) |
|
538 | + |
|
539 | +- [404 Blog Not Found:perl - Encode 入門](http://blog.livedoor.jp/dankogai/archives/51031595.html) |
|
540 | +- [use threads; するときに注意すべきこと - punitan (a.k.a. punytan) のメモ](http://d.hatena.ne.jp/punitan/20091018/1255892339)<br /> |
|
541 | +threads と binmode を同時に使うとクラッシュする。 |
|
542 | + |
|
543 | +- [404 Blog Not Found:perl - 勝手に添削 - Webサイト死活管理](http://blog.livedoor.jp/dankogai/archives/51511557.html) |
|
544 | + |
|
545 | +- [お手軽に死活監視をPerlのCPANモジュールApp::MadEyeで行う](http://hirobanex.net/article/2012/02/1330308330) @ [hirobanex.net](http://hirobanex.net/) |
|
546 | + |
|
547 | +- [gWakeOnLan](http://code.google.com/p/gwakeonlan/)<br />gWakeOnLan is a GTK+ utility to awake turned off machines using the Wake on LAN feature. |
|
... | ... | \ No newline at end of file |
Perl/Perl-Tidy.md
... | ... | @@ -0,0 +1,43 @@ |
1 | +# インストール |
|
2 | + |
|
3 | +## Windows Active Perl |
|
4 | +``` |
|
5 | +> ppm install perl-tidy |
|
6 | +``` |
|
7 | +- ホームフォルダに設定ファイルを作成 |
|
8 | +``` |
|
9 | +%HOMEPATH%/.perltidyrc |
|
10 | +``` |
|
11 | + |
|
12 | +## Linux |
|
13 | +``` |
|
14 | +# cpanm Perl::Tidy |
|
15 | +``` |
|
16 | +- ホームフォルダに設定ファイルを作成 |
|
17 | +``` |
|
18 | +$HOME/.perltidyrc |
|
19 | +``` |
|
20 | + |
|
21 | +# ウチの設定 |
|
22 | +``` |
|
23 | +-l=100 # Max line width is 100 cols |
|
24 | +-i=4 # Indent level is 4 cols |
|
25 | +-ci=4 # Continuation indent is 4 cols |
|
26 | +#-st # Output to STDOUT |
|
27 | +-se # Errors to STDERR |
|
28 | +-vt=2 # Maximal vertical tightness |
|
29 | +-cti=0 # No extra indentation for closing brackets |
|
30 | +-pt=1 # Medium parenthesis tightness |
|
31 | +-bt=1 # Medium brace tightness |
|
32 | +-sbt=1 # Medium square brace tightness |
|
33 | +-bbt=1 # Medium block brace tightness |
|
34 | +-nsfs # No space before semicolons |
|
35 | +-nolq # Don't outdent long quoted strings |
|
36 | +-wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" |
|
37 | + # Break before all operators |
|
38 | +-b # backup original to .bak and modify file in-place |
|
39 | +-ce # cuddled else; use this style: '} else {' |
|
40 | +``` |
|
41 | + |
|
42 | +# リンク |
|
43 | +- [CPAN:Perl-Tidy](http://search.cpan.org/dist/Perl-Tidy) |
|
... | ... | \ No newline at end of file |
Perl/SHA1.md
... | ... | @@ -0,0 +1,86 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- ファイルから平文を読み込んでSHA1を計算する。 |
|
5 | + |
|
6 | +# ソース |
|
7 | +- [sha1.zip](sha1.zip) |
|
8 | + |
|
9 | +## sha1.pl |
|
10 | +```perl |
|
11 | +# SHA1 の計算 |
|
12 | + |
|
13 | +use strict; |
|
14 | +use warnings; |
|
15 | +use utf8; |
|
16 | +use Encode; |
|
17 | +use Digest::SHA1 qw( sha1_hex ); |
|
18 | + |
|
19 | +my $charsetConsole = 'CP932'; |
|
20 | +my $charsetFile = 'utf-8'; |
|
21 | + |
|
22 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
23 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
24 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
25 | + |
|
26 | +my $srcFile = "./Password_Org.txt"; |
|
27 | +my $dstFile = "./Password_Enc.txt"; |
|
28 | + |
|
29 | +open( my $fhin, "<:utf8", encode( $charsetConsole, $srcFile ) ) |
|
30 | + or die( "$srcFile: $!\n" ); |
|
31 | +<$fhin>; # ヘッダ行を捨てる |
|
32 | +my @Body = <$fhin>; |
|
33 | +close( $fhin ); |
|
34 | +chomp( @Body ); |
|
35 | + |
|
36 | +open( my $fhout, ">:utf8", encode( $charsetConsole, $dstFile ) ) |
|
37 | + or die( "$dstFile: $!\n" ); |
|
38 | +print $fhout "ID\tPlain\tEncrypted\n"; |
|
39 | + |
|
40 | +foreach my $row ( @Body ){ |
|
41 | + my @fields = split( /\t/, $row ); |
|
42 | + printf $fhout ( "%s\t%s\n", $row, sha1_hex( encode( 'utf8', $fields[1] ) ) ); |
|
43 | +} |
|
44 | + |
|
45 | +close( $fhout ); |
|
46 | + |
|
47 | +# EOF |
|
48 | +``` |
|
49 | + |
|
50 | +# 計算サンプル |
|
51 | +## 入力 Password_Org.txt |
|
52 | +``` |
|
53 | +ID Plain |
|
54 | +1 0000 |
|
55 | +2 1111 |
|
56 | +3 2222 |
|
57 | +4 3333 |
|
58 | +5 あいう |
|
59 | +``` |
|
60 | + |
|
61 | +## 出力 Password_Enc.txt |
|
62 | +``` |
|
63 | +ID Plain Encrypted |
|
64 | +1 0000 39dfa55283318d31afe5a3ff4a0e3253e2045e43 |
|
65 | +2 1111 011c945f30ce2cbafc452f39840f025693339c42 |
|
66 | +3 2222 fea7f657f56a2a448da7d4b535ee5e279caf3d9a |
|
67 | +4 3333 f56d6351aa71cff0debea014d13525e42036187a |
|
68 | +5 あいう eb636ba7c320e00b3749ad404b7adc7609560dee |
|
69 | +``` |
|
70 | + |
|
71 | +# SHA256 ハッシュの計算 |
|
72 | + |
|
73 | +## perl |
|
74 | +``` |
|
75 | +perl -MDigest::SHA -e 'my $sha = Digest::SHA->new(256); $sha->addfile("filename"); print $sha->b64digest . "\n";' |
|
76 | +``` |
|
77 | + |
|
78 | +## OpenSSL |
|
79 | +``` |
|
80 | +openssl sha256 -binary "filename" | openssl base64 |
|
81 | +``` |
|
82 | + |
|
83 | +# リンク |
|
84 | +- [CPAN:Digest](http://search.cpan.org/dist/Digest) |
|
85 | +- [CPAN:Digest-SHA](http://search.cpan.org/dist/Digest-SHA) |
|
86 | +- [CPAN:Digest-SHA1](http://search.cpan.org/dist/Digest-SHA1) |
|
... | ... | \ No newline at end of file |
Perl/SortUnicode.md
... | ... | @@ -0,0 +1,51 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- Unicode 順でのソート。 |
|
5 | +- ひらがな/カタカナを区別せずにソートするには「Unicode::Collate」でソートする。 |
|
6 | + |
|
7 | +# ソース |
|
8 | +- [sortUnicode.zip](sortUnicode.zip) |
|
9 | +```perl |
|
10 | +#!/usr/bin/perl |
|
11 | +# Unicode 順のソート |
|
12 | + |
|
13 | +use strict; |
|
14 | +use warnings; |
|
15 | +use utf8; |
|
16 | +use Encode; |
|
17 | +use POSIX qw(locale_h); |
|
18 | +use locale; |
|
19 | +use Unicode::Collate; |
|
20 | + |
|
21 | +my $charsetConsole = 'UTF-8'; |
|
22 | + |
|
23 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
24 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
25 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
26 | + |
|
27 | +my @list = split( //, 'あぁAAアアaはばぱがかぴひび' ); |
|
28 | + |
|
29 | +my $locale = "ja_JP.UTF-8"; |
|
30 | +setlocale( LC_ALL, $locale ); |
|
31 | +print "locale($locale)\n"; |
|
32 | +print join( "", sort(@list) ) . "\n"; |
|
33 | +print "\n"; |
|
34 | +my $Collator = Unicode::Collate->new(); |
|
35 | +print "Unicode::Collate\n"; |
|
36 | +print join( "", $Collator->sort(@list) ) . "\n"; |
|
37 | +``` |
|
38 | + |
|
39 | +# 出力 |
|
40 | +- Cent OS 6, perl v5.10.1 |
|
41 | +``` |
|
42 | +locale(ja_JP.UTF-8) |
|
43 | +AaアAぁあかがはばぱひびぴア |
|
44 | + |
|
45 | +Unicode::Collate |
|
46 | +aAAぁあアアかがはばぱひびぴ |
|
47 | +``` |
|
48 | + |
|
49 | +# リンク |
|
50 | +- [CPAN:Unicode-Collate](http://search.cpan.org/dist/Unicode-Collate) |
|
51 | +- [Perl のロケール操作 (国際化と地域化)](http://perldoc.jp/pod/perllocale) |
|
... | ... | \ No newline at end of file |
Perl/W03_FOMA.md
... | ... | @@ -0,0 +1,101 @@ |
1 | +# W-ZERO3のアドレス帳をFOMAのデータリンクソフト用に変換 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- [アドレス帳CSVコンバータ](http://dev.officeservice.co.jp/top/index.php?%A5%BD%A5%D5%A5%C8%A5%A6%A5%A7%A5%A2%2FPocketPC%2FPOCSV)でCSVに書き出した[W-ZERO3]]のアドレス帳を、FOMA [[N701i](http://www.n-keitai.com/n701i/opn.html)に[データリンクソフト](http://www.n-keitai2.com/guide/download/index.html)で読み込める形式に変換する。 |
|
6 | + |
|
7 | +## ソースコード |
|
8 | +``` |
|
9 | +$fin = "W03.csv"; |
|
10 | +$fout = "FOMA.csv"; |
|
11 | + |
|
12 | +# メモリ番号の最初の値 |
|
13 | +$MemoryNo = 10; |
|
14 | + |
|
15 | +@TelKeys =( |
|
16 | + "BusinessTelephoneNumber", "BusinessFaxNumber", "CompanyTelephoneNumber", |
|
17 | + "MobileTelephoneNumber", "HomeTelephoneNumber", "Home2TelephoneNumber", |
|
18 | +); |
|
19 | + |
|
20 | +@EMailKeys = ( |
|
21 | + "Email1Address", "Email2Address", "Email3Address", |
|
22 | +); |
|
23 | + |
|
24 | +%Icon =( |
|
25 | + "BusinessTelephoneNumber" => 3, "BusinessFaxNumber" => 4, "CompanyTelephoneNumber" => 3, |
|
26 | + "MobileTelephoneNumber" => 1, "HomeTelephoneNumber" => 2, "Home2TelephoneNumber" => 2, |
|
27 | + "Email1Address" => 24, "Email2Address" => 24, "Email3Address" => 24, |
|
28 | +); |
|
29 | + |
|
30 | +open( IN, $fin ) || die( "can't open'".$fin."'.\n" ); |
|
31 | +open( OUT, ">".$fout ) || die( "can't open'".$fout."'.\n" ); |
|
32 | + |
|
33 | +$line = <IN>; |
|
34 | +chop( $line ); |
|
35 | +@fields = split( ",", $line ); |
|
36 | +@addr_in = <IN>; |
|
37 | +close( IN ); |
|
38 | +chop( @addr_in ); |
|
39 | + |
|
40 | +for( $i=0; $i<@addr_in; ++$i ){ |
|
41 | + @addr_tmp = split( ",", $addr_in[ $i ] ); |
|
42 | + %addr_out = (); |
|
43 | + for( $j=0; $j<@fields; ++$j ){ |
|
44 | + if ( $addr_tmp[ $j ] =~ /^"(.*)"$/ ){ |
|
45 | + $addr_tmp[ $j ] = $1; |
|
46 | + } |
|
47 | + $addr_out{ $fields[ $j ] } = $addr_tmp[ $j ]; |
|
48 | + } |
|
49 | + |
|
50 | + $Name = $addr_out{ "FileAs" }; |
|
51 | + $Yomi = $addr_out{ "YomiLastName" }.$addr_out{ "YomiFirstName" }; |
|
52 | + $Group = "0"; |
|
53 | + $Secret = "0"; |
|
54 | + $PostalCode = $addr_out{ "BusinessAddressPostalCode" }; |
|
55 | + $Addr = $addr_out{ "BusinessAddressState" }.$addr_out{ "BusinessAddressCity" }.$addr_out{ "BusinessAddressStreet" }; |
|
56 | + $Memo = $addr_out{ "CompanyName" }; |
|
57 | + if ( $addr_out{ "Birthday" } ne "" ){ |
|
58 | + $Birthday = "19".$addr_out{ "Birthday" }; |
|
59 | + } |
|
60 | + $step = 0; |
|
61 | + foreach $telkey ( @TelKeys ){ |
|
62 | + $addr_out{ $telkey } =~ tr/-() //d; |
|
63 | + if ( $addr_out{ $telkey } ne "" ){ |
|
64 | + printf OUT ( |
|
65 | + "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", |
|
66 | + $MemoryNo+$i+$step, $Name, $Yomi, $addr_out{ $telkey }, $Group, $Icon{ $telkey }, |
|
67 | + $Secret, "", $PostalCode, $Addr, $Memo, $Birthday |
|
68 | + ); |
|
69 | + $step += 700; |
|
70 | + } |
|
71 | + } |
|
72 | + $step = 2800; |
|
73 | + foreach $emailkey ( @EMailKeys ){ |
|
74 | + if ( $addr_out{ $emailkey } ne "" ){ |
|
75 | + printf OUT ( |
|
76 | + "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", |
|
77 | + $MemoryNo+$i+$step, $Name, $Yomi, "", $Group, $Icon{ $emailkey }, |
|
78 | + $Secret, $addr_out{ $emailkey }, $PostalCode, $Addr, $Memo, $Birthday |
|
79 | + ); |
|
80 | + $step += 700; |
|
81 | + } |
|
82 | + } |
|
83 | + |
|
84 | +} |
|
85 | + |
|
86 | +close( OUT ); |
|
87 | + |
|
88 | +# EOF |
|
89 | +``` |
|
90 | + |
|
91 | +## アイコン番号 |
|
92 | +| | 固定電話 | |
|
93 | +| --- | --- | |
|
94 | +| 1 | 携帯電話 | |
|
95 | +| 2 | 自宅電話 | |
|
96 | +| 3 | 会社電話 | |
|
97 | +| 4 | 会社FAX | |
|
98 | +| 24 | 一般メール | |
|
99 | +| 25 | 自宅メール | |
|
100 | +| 26 | 会社メール | |
|
101 | +| 27 | 携帯メール | |
|
... | ... | \ No newline at end of file |
Perl/WhoisGW.md
... | ... | @@ -0,0 +1,124 @@ |
1 | +# WhoisGW |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- jwhois を実行し、ドメイン管理者情報を表示します。 |
|
6 | +- spam 送信の元になるため、パスワードを設定するなどして濫用させないようにすること。 |
|
7 | + |
|
8 | +## ソース |
|
9 | +- [WhoisGW.zip](WhoisGW.zip) |
|
10 | + |
|
11 | +### WhoisGW.cgi |
|
12 | +```perl |
|
13 | +#!/usr/bin/perl |
|
14 | +# Whois ゲートウェイ |
|
15 | +# spam 送信の元になるため、パスワードを設定するなどして濫用させないようにすること。 |
|
16 | + |
|
17 | +use strict; |
|
18 | +use warnings; |
|
19 | +use utf8; |
|
20 | +use Encode; |
|
21 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
22 | + |
|
23 | +my $charsetConsole = 'UTF-8'; |
|
24 | +my $charsetFile = 'UTF-8'; |
|
25 | + |
|
26 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
27 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
28 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
29 | + |
|
30 | +my $cgiName = 'WhoisGW'; |
|
31 | + |
|
32 | +my $q = new CGI; |
|
33 | +$q->charset( $charsetConsole ); |
|
34 | + |
|
35 | +my $domain = $q->param( 'domain' ) || ''; |
|
36 | + |
|
37 | +print makeHeader(); |
|
38 | +if ( $domain ){ |
|
39 | + if ( $domain =~ /^(\d+\.\d+\.\d+\.\d+|[a-z0-9][\-\.a-z0-9]+[a-z0-9])$/i ){ |
|
40 | + print execWhois( $domain ); |
|
41 | + } else { |
|
42 | + print makeForm(); |
|
43 | + print $q->p('ドメイン名が不正です。'); |
|
44 | + } |
|
45 | +} else { |
|
46 | + print makeForm(); |
|
47 | +} |
|
48 | +print makeFooter(); |
|
49 | + |
|
50 | +exit; |
|
51 | + |
|
52 | +sub makeHeader |
|
53 | +{ |
|
54 | + my $ret = ''; |
|
55 | + $ret .= $q->header(); |
|
56 | + $ret .= $q->start_html( |
|
57 | + -title => $cgiName, |
|
58 | + -lang => 'ja-JP', |
|
59 | + -head => [ |
|
60 | + $q->meta( { -http_equiv => 'Content-style-type', -content => 'text/css' } ), |
|
61 | + $q->meta( { -http_equiv => 'Content-script-type', -content => 'text/javascript' } ), |
|
62 | + ], |
|
63 | + -style => [ { -src => '/take.css' }, ], |
|
64 | + ); |
|
65 | + $ret .= $q->h1( $q->a( { -href => $q->url }, $cgiName ) ); |
|
66 | + return $ret; |
|
67 | +} |
|
68 | + |
|
69 | +sub makeFooter |
|
70 | +{ |
|
71 | + my $ret = ''; |
|
72 | + $ret .= $q->end_html . "\n"; |
|
73 | + return $ret; |
|
74 | +} |
|
75 | + |
|
76 | +sub execWhois |
|
77 | +{ |
|
78 | + my $domain = shift || ''; |
|
79 | + my $ret = $q->pre( join( "", `jwhois -df $domain` ) ); |
|
80 | + return $ret; |
|
81 | +} |
|
82 | + |
|
83 | +sub makeForm |
|
84 | +{ |
|
85 | + my $ret = ''; |
|
86 | + $ret .= $q->start_form( |
|
87 | + -action => $q->url, |
|
88 | + -enctype => 'multipart/form-data', |
|
89 | + ); |
|
90 | + $ret .= $q->start_table( { -summary => 'Parameters', -border => 1 } ); |
|
91 | + $ret .= $q->Tr( |
|
92 | + $q->th( 'Domain' ), |
|
93 | + $q->td( $q->textfield( -name => 'domain', -size => 50 ) ), |
|
94 | + ); |
|
95 | + $ret .= $q->Tr( $q->th( |
|
96 | + { -colspan => 2, -align => 'center' }, |
|
97 | + $q->submit( -name => 'action', -value => 'search' ), |
|
98 | + ) ); |
|
99 | + $ret .= $q->end_table(); |
|
100 | + $ret .= $q->end_form; |
|
101 | + return $ret; |
|
102 | +} |
|
103 | + |
|
104 | +# EOF |
|
105 | +``` |
|
106 | + |
|
107 | +### WhoisGW.conf |
|
108 | +```apache |
|
109 | +<Directory "/var/www/html/WhoisGW"> |
|
110 | + AllowOverride AuthConfig |
|
111 | + AuthType Digest |
|
112 | + AuthName "WhoisGW" |
|
113 | + AuthUserFile /var/www/passwd/passwords_digest |
|
114 | + Require user whois |
|
115 | + Options +ExecCGI |
|
116 | + DirectoryIndex index.html index.htm index.cgi |
|
117 | + Order allow,deny |
|
118 | + Allow from all |
|
119 | +</Directory> |
|
120 | +``` |
|
121 | + |
|
122 | +## リンク |
|
123 | +- [aguse.jp](http://www.aguse.jp/) ウェブ調査 |
|
124 | +- [ANSI Whois Gateway](http://whois.ansi.co.jp/) ドメイン名 / IPアドレス検索サービス |
|
... | ... | \ No newline at end of file |
Perl/Windows_DLL_Call.md
... | ... | @@ -0,0 +1,132 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# MessageBox |
|
4 | +## 概要 |
|
5 | +- [MessageBox function](http://msdn.microsoft.com/en-us/library/windows/desktop/ms645505.aspx)を呼び出す。 |
|
6 | + |
|
7 | +## ソース |
|
8 | +- [Win32MsdBox.zip](Win32MsdBox.zip) |
|
9 | +```perl |
|
10 | +#!/usr/bin/perl |
|
11 | + |
|
12 | +use strict; |
|
13 | +use warnings; |
|
14 | +use utf8; |
|
15 | +use Encode; |
|
16 | +use Win32::Unicode::Native; |
|
17 | +use Win32::API; |
|
18 | + |
|
19 | +#my $charsetFile = 'UTF-8'; |
|
20 | +my $charsetConsole = 'CP932'; |
|
21 | +my $charsetApiA = 'CP932'; |
|
22 | +my $charsetApiW = 'UTF-16LE'; |
|
23 | + |
|
24 | +my $message = "Hello, world!\nこんにちは世界?"; |
|
25 | +my $type = 0x0000_0004 | 0x0000_0020; |
|
26 | + |
|
27 | +print "コンソール\n${message}\n"; |
|
28 | + |
|
29 | +my $messageBoxA = Win32::API::More->new( |
|
30 | + 'User32', |
|
31 | + 'int MessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)' |
|
32 | +) or die(decode($charsetConsole, Win32::FormatMessage(Win32::GetLastError()))); |
|
33 | +my $retA = $messageBoxA->Call( |
|
34 | + 0, encode($charsetApiA, $message), encode($charsetApiA, "ApiA 版"), $type |
|
35 | +); |
|
36 | +print "${retA}\n"; |
|
37 | + |
|
38 | +my $win32w = Win32::API::More->Import( |
|
39 | + 'User32', |
|
40 | + 'int MessageBoxW(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)' |
|
41 | +) or die(decode($charsetConsole, Win32::FormatMessage(Win32::GetLastError()))); |
|
42 | +my $retW = MessageBoxW( |
|
43 | + 0, encode($charsetApiW, $message), encode($charsetApiW, "ApiW 版"), $type |
|
44 | +); |
|
45 | +print "${retW}\n"; |
|
46 | + |
|
47 | +# EOF |
|
48 | +``` |
|
49 | + |
|
50 | +# 郵政バーコード |
|
51 | +## 概要 |
|
52 | +- [Rolan社](http://www.rolan.co.jp/)の[郵便カスタマーバーコード開発キット](http://www.rolan.co.jp/shouhin/s_yubar.html)を呼び出す。 |
|
53 | +- 住所データベース中の「郵便番号」と「丁目番地」から郵政バーコードを計算する。 |
|
54 | + |
|
55 | +## ソース |
|
56 | +- [YuBar.zip](YuBar.zip) |
|
57 | +- Rolan社の YuBar.dll がインストールされていないと動作しません。 |
|
58 | +- 住所データベースは架空のものであって、実在の人物、住所とは関係ありません。 |
|
59 | +```perl |
|
60 | +# 郵政バーコード作成 (Rolan社 YuBar) |
|
61 | +# 郵便カスタマーバーコード開発キット http://www.rolan.co.jp/shouhin/s_yubar.html |
|
62 | + |
|
63 | +use strict; |
|
64 | +use warnings; |
|
65 | +use utf8; |
|
66 | +use encoding 'Shift_JIS'; |
|
67 | +use Win32::API; |
|
68 | +#use Data::Dump 'dump'; |
|
69 | + |
|
70 | +my $FileIn = 'Customer.txt'; # 入力ファイル |
|
71 | +my $FileOut = 'Customer2.txt'; # 出力ファイル |
|
72 | + |
|
73 | +open( IN, "<:encoding(Shift_JIS)", $FileIn ) || die( "can't open'".$FileIn."'.\n" ); |
|
74 | +open( OUT, ">:encoding(Shift_JIS)", $FileOut ) || die( "can't open'".$FileOut."'.\n" ); |
|
75 | + |
|
76 | +# ヘッダ行解析 |
|
77 | +my $Line = <IN>; |
|
78 | +$Line =~ /(\s+)$/; |
|
79 | +$/ = $1; # 改行コード設定 |
|
80 | +chomp( $Line ); |
|
81 | +my @Fields = split( "\t", $Line ); |
|
82 | +my $i = 0; |
|
83 | +#my %FN2I = (); # FieldName to Index |
|
84 | +#foreach $_ ( @Fields ){ |
|
85 | +# $_ =~ s/^"(.*)"$/$1/; |
|
86 | +# $FN2I{ $_ } = $i++; |
|
87 | +#} |
|
88 | +my %FN2I = map{ s/^"(.*)"$/$1/; $_ => $i++; } @Fields; |
|
89 | + |
|
90 | +#print dump( %FN2I ); |
|
91 | + |
|
92 | +print OUT $Line . "\t\"YuBar\"\n"; |
|
93 | + |
|
94 | +my( @Records, $ZipCode, $Street, $YuBar ); |
|
95 | + |
|
96 | +while( $Line = <IN> ){ |
|
97 | + chomp( $Line ); |
|
98 | + @Records = split( "\t", $Line ); |
|
99 | + $ZipCode = $Records[ $FN2I{ 'ZipCode' } ]; |
|
100 | + $ZipCode =~ s/^"(.*)"$/$1/; |
|
101 | + $Street = $Records[ $FN2I{ 'Addr2' } ]; |
|
102 | + $Street =~ s/^"(.*)"$/$1/; |
|
103 | + $YuBar = &YuBar( $ZipCode, $Street ); |
|
104 | + printf OUT ( "%s\t\"%s\"\n", $Line, $YuBar ); |
|
105 | +} |
|
106 | + |
|
107 | +close( IN ); |
|
108 | +close( OUT ); |
|
109 | + |
|
110 | +exit(); |
|
111 | + |
|
112 | +sub YuBar |
|
113 | +{ |
|
114 | + my( $ZipCode, $Street ) = @_; |
|
115 | + my $GetYuBar = new Win32::API("YuBar", "YubinBarcode", 'PPP', 'I'); |
|
116 | + my $YuBarStr = "\x00" x 23; |
|
117 | + my $Ret = ($GetYuBar->Call($ZipCode, $Street, $YuBarStr) & 0xFFFF); |
|
118 | + return $YuBarStr; |
|
119 | +} |
|
120 | + |
|
121 | +# EOF |
|
122 | +``` |
|
123 | + |
|
124 | +## リンク |
|
125 | +- [CPAN:Win32-API](http://search.cpan.org/dist/Win32-API) |
|
126 | + |
|
127 | +- [Rolan](http://www.rolan.co.jp/) |
|
128 | + - [郵便カスタマーバーコード開発キット](http://www.rolan.co.jp/shouhin/s_yubar.html) |
|
129 | + |
|
130 | +- [郵便番号](http://www.post.japanpost.jp/zipcode/) |
|
131 | + - [郵便番号制マニュアル](http://www.post.japanpost.jp/zipcode/zipmanual/) |
|
132 | + - [ダウンロード](http://www.post.japanpost.jp/zipcode/download.html) |
|
... | ... | \ No newline at end of file |
Perl/XML-Simple.md
... | ... | @@ -0,0 +1 @@ |
1 | +~~#include(Perl/Amazon/BrowseNodeSearch,notitle)~~ |
|
... | ... | \ No newline at end of file |
Perl/XML-XPath.md
... | ... | @@ -0,0 +1,71 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- XPathを使ってXMLを読む。 |
|
5 | + |
|
6 | +# サンプルXML |
|
7 | +- [Monitor_6500K.zip](Monitor_6500K.zip) |
|
8 | + |
|
9 | +# ソース |
|
10 | +- dumpCXF.pl |
|
11 | +```perl |
|
12 | +#!/usr/local/bin/perl |
|
13 | + |
|
14 | +# CxF file からスペクトルの値を抜き出して表示 |
|
15 | +# by take-ash |
|
16 | +# 2006.01.13 |
|
17 | +# 注) 文字コード:UTF-8N、改行:LF で、このperlスクリプトを保存すること。 |
|
18 | + |
|
19 | +use strict; |
|
20 | +use utf8; |
|
21 | +use XML::XPath; |
|
22 | +#use Data::Dump qw(dump); |
|
23 | + |
|
24 | +my $xp = XML::XPath->new( filename => 'Monitor_6500K.cxf' ); |
|
25 | +# print dump( $xp ); |
|
26 | + |
|
27 | +my $nodeset_samples = $xp->find( '/CXF/SampleSet/Sample' ); |
|
28 | + |
|
29 | +foreach my $node_sample ( $nodeset_samples->get_nodelist() ) { |
|
30 | + my $name = $xp->findvalue( './Name', $node_sample ); |
|
31 | + printf( "Name:\t%s\n", $name ); |
|
32 | + |
|
33 | + my $nodeset_values = $xp->find( './SampleAttribute/Spectrum/Value', $node_sample ); |
|
34 | + foreach my $node_value ( $nodeset_values->get_nodelist() ) { |
|
35 | + my $name = $xp->findvalue( './@Name', $node_value ); |
|
36 | + my $value = $xp->findvalue( '.', $node_value ); |
|
37 | + printf( "%s\t%s\n", $name, $value ); |
|
38 | + } |
|
39 | + print "\n"; |
|
40 | +} |
|
41 | + |
|
42 | +#EOF |
|
43 | +``` |
|
44 | + |
|
45 | +# XPathモジュールのインストール |
|
46 | +``` |
|
47 | +ppm install XML-XPath |
|
48 | +``` |
|
49 | + |
|
50 | +# DTD を読ませない |
|
51 | +- DTD を読ませないようにするには、LWP を無効化したパーサを指定する。 |
|
52 | +```perl |
|
53 | +my $p = XML::Parser->new( NoLWP => 1 ); |
|
54 | +my $xp = XML::XPath->new( parser => $p, filename => "a.xhtml" ); |
|
55 | +``` |
|
56 | + |
|
57 | +- [How can I prevent XML::XPath from fetching a DTD while processing an XML file? - Stack Overflow](http://stackoverflow.com/questions/303510/) |
|
58 | + |
|
59 | +# リンク |
|
60 | +- Perl/XML-Simple |
|
61 | + |
|
62 | +- [CPAN:XML-XPath](http://search.cpan.org/dist/XML-XPath) |
|
63 | + - [Node/Element](http://search.cpan.org/dist/XML-XPath/lib/XML/XPath/Node/Element.pm) |
|
64 | + |
|
65 | +- [Walrus,Digit.:Perlモジュール/インストール(PPM)](http://digit.que.ne.jp/work/index.cgi?%50%65%72%6c%a5%e2%a5%b8%a5%e5%a1%bc%a5%eb%2f%a5%a4%a5%f3%a5%b9%a5%c8%a1%bc%a5%eb%28%50%50%4d%29) |
|
66 | + |
|
67 | +- [PerlでXMLを扱う](http://park8.wakwak.com/~da101/nikky/archives/000103.html) |
|
68 | + |
|
69 | +- [Perl XMLでencoding='Shift_JIS'や'euc-jp'を使う](http://homepage3.nifty.com/hippo2000/perltips/xml/xmlenc.htm) |
|
70 | + |
|
71 | +- [CxF](http://www.xrite.com/color-exchange-format) Color Exchange Format |
|
... | ... | \ No newline at end of file |
Perl/YAML.md
... | ... | @@ -0,0 +1,400 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 記号の読み込みテスト |
|
4 | + |
|
5 | +## 概要 |
|
6 | +- 記号そのものを値として読み込みたい場合、"" または '' で括る必要がある。 |
|
7 | + |
|
8 | +## ソース |
|
9 | +- [marks.zip](marks.zip) |
|
10 | + |
|
11 | +- marks.pl |
|
12 | +```perl |
|
13 | +# YAML 記号の読み込みテスト |
|
14 | +# ハイフン, コロン, 角括弧, 波括弧, ハッシュ記号, |
|
15 | +# バックスラッシュ, シングルクォート, ダブルクォート, |
|
16 | +# 改行, タブ等の# 記号そのものを値として読み込みたい場合、 |
|
17 | +# "" または '' で括る必要がある。 |
|
18 | + |
|
19 | +use strict; |
|
20 | +use warnings; |
|
21 | +use utf8; |
|
22 | +use Encode; |
|
23 | +use YAML::Syck; |
|
24 | +use Data::Dump qw(dump); |
|
25 | + |
|
26 | +$YAML::Syck::ImplicitUnicode = 1; |
|
27 | + |
|
28 | +my $charset = 'CP932'; |
|
29 | + |
|
30 | +binmode( STDIN, ":encoding($charset)" ); |
|
31 | +binmode( STDOUT, ":encoding($charset)" ); |
|
32 | +binmode( STDERR, ":encoding($charset)" ); |
|
33 | + |
|
34 | +# バージョン確認 |
|
35 | +print "Perl version: " . $] . "\n"; |
|
36 | +print "YAML::Syck version: " . $YAML::Syck::VERSION . "\n"; |
|
37 | + |
|
38 | +# 括るまたはエスケープ |
|
39 | +my $MarksFile = './marks.yaml'; |
|
40 | +my $MarksIn = YAML::Syck::LoadFile( $MarksFile ) or die( "$MarksFile:$!" ); |
|
41 | +print dump( $MarksIn ) . "\n"; |
|
42 | + |
|
43 | +# 変数をシリアライズ |
|
44 | +my $MarksOut = [ '-', ':', '[', ']', '{', '}', '#', '\\', '\'', '\"', "\n", "\t", ]; |
|
45 | +print Dump( $MarksOut ) . "\n"; |
|
46 | + |
|
47 | +# EOF |
|
48 | +``` |
|
49 | + |
|
50 | +- marks.yaml |
|
51 | +``` |
|
52 | +--- |
|
53 | +- "-" |
|
54 | +- ":" |
|
55 | +- "[" |
|
56 | +- "]" |
|
57 | +- "{" |
|
58 | +- "}" |
|
59 | +- # |
|
60 | +- \# |
|
61 | +- "#" |
|
62 | +- \ |
|
63 | +- \\ |
|
64 | +- \' |
|
65 | +- "'" |
|
66 | +- \" |
|
67 | +- '"' |
|
68 | +- \n |
|
69 | +- "\n" |
|
70 | +- \t |
|
71 | +- "\t" |
|
72 | +``` |
|
73 | + |
|
74 | +## 出力結果 |
|
75 | +``` |
|
76 | +Perl version: 5.010001 |
|
77 | +YAML::Syck version: 1.15 |
|
78 | +[ |
|
79 | + "-", |
|
80 | + ":", |
|
81 | + "[", |
|
82 | + "]", |
|
83 | + "{", |
|
84 | + "}", |
|
85 | + undef, |
|
86 | + "\\#", |
|
87 | + "#", |
|
88 | + "\\", |
|
89 | + "\\\\", |
|
90 | + "\\'", |
|
91 | + "'", |
|
92 | + "\\\"", |
|
93 | + "\"", |
|
94 | + "\\n", |
|
95 | + "\n", |
|
96 | + "\\t", |
|
97 | + "\t", |
|
98 | +] |
|
99 | +--- |
|
100 | +- "-" |
|
101 | +- ":" |
|
102 | +- "[" |
|
103 | +- "]" |
|
104 | +- "{" |
|
105 | +- "}" |
|
106 | +- "#" |
|
107 | +- \ |
|
108 | +- "'" |
|
109 | +- \" |
|
110 | +- "\n" |
|
111 | +- "\t" |
|
112 | +``` |
|
113 | + |
|
114 | +# 16進数等の読み込み |
|
115 | + |
|
116 | +## 概要 |
|
117 | +- YAML::Syck で16進数等を解釈させたい場合は「$YAML::Syck::ImplicitTyping = 1;」が必要。 |
|
118 | + |
|
119 | +## ソース |
|
120 | +- [NumberString1.zip](NumberString1.zip) |
|
121 | + |
|
122 | +- NumberString1.pl |
|
123 | +```perl |
|
124 | +#!/usr/bin/perl |
|
125 | +# YamlString.pl |
|
126 | +# YAML::Syck での数値文字列の読み込みテスト |
|
127 | +# 数値や論理値等として解釈させるには「$YAML::Syck::ImplicitTyping = 1;」が必要。 |
|
128 | + |
|
129 | +use strict; |
|
130 | +use warnings; |
|
131 | +use utf8; |
|
132 | +use Encode; |
|
133 | +use YAML::Syck qw( Load Dump ); |
|
134 | + |
|
135 | +$YAML::Syck::ImplicitUnicode = 1; |
|
136 | + |
|
137 | +#my $charsetConsole = 'UTF-8'; |
|
138 | +my $charsetConsole = 'CP932'; |
|
139 | +my $charsetFile = 'UTF-8'; |
|
140 | + |
|
141 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
142 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
143 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
144 | + |
|
145 | +# バージョン確認 |
|
146 | +print "Perl version: $]\n"; |
|
147 | +print "YAML::Syck version: $YAML::Syck::VERSION\n"; |
|
148 | + |
|
149 | +my $yamlString = qq{ |
|
150 | +Decimal: [ 0, 1, 2, 4, 8, 10, 16 ] |
|
151 | +Binal: [ 0b00000, 0b00001, 0b00010, 0b00100, 0b01000, 0b01010, 0b10000 ] |
|
152 | +Octal: [ 000, 001, 002, 004, 010, 012, 020 ] |
|
153 | +Hexadecimal: [ 0x00, 0x01, 0x02, 0x04, 0x08, 0x0a, 0x10 ] |
|
154 | +Boolean: [ true, false, yes, no, on, off, null, ~ ] |
|
155 | +漢字: [ 壱, 弐, 参, 四, 五 ] |
|
156 | +HexKey: { 0x00: "00", 0x01: "01", 0x02: "02", 0x04: "04", 0x08: "08", 0x0a: "0a", 0x10: "10" } |
|
157 | +}; |
|
158 | + |
|
159 | +$YAML::Syck::ImplicitTyping = 0; # Default |
|
160 | +print "\n\$YAML::Syck::ImplicitTyping = 0\n"; |
|
161 | +print Dump( Load( $yamlString ) ); |
|
162 | + |
|
163 | +$YAML::Syck::ImplicitTyping = 1; |
|
164 | +print "\n\$YAML::Syck::ImplicitTyping = 1\n"; |
|
165 | +print Dump( Load( $yamlString ) ); |
|
166 | + |
|
167 | +# EOF |
|
168 | +``` |
|
169 | + |
|
170 | +## 出力結果 |
|
171 | +``` |
|
172 | +Perl version: 5.014002 |
|
173 | +YAML::Syck version: 1.21 |
|
174 | + |
|
175 | +$YAML::Syck::ImplicitTyping = 0 |
|
176 | +--- |
|
177 | +Binal: |
|
178 | + - 0b00000 |
|
179 | + - 0b00001 |
|
180 | + - 0b00010 |
|
181 | + - 0b00100 |
|
182 | + - 0b01000 |
|
183 | + - 0b01010 |
|
184 | + - 0b10000 |
|
185 | +Boolean: |
|
186 | + - 'true' |
|
187 | + - 'false' |
|
188 | + - 'yes' |
|
189 | + - 'no' |
|
190 | + - 'on' |
|
191 | + - 'off' |
|
192 | + - 'null' |
|
193 | + - ~ |
|
194 | +Decimal: |
|
195 | + - 0 |
|
196 | + - 1 |
|
197 | + - 2 |
|
198 | + - 4 |
|
199 | + - 8 |
|
200 | + - 10 |
|
201 | + - 16 |
|
202 | +HexKey: |
|
203 | + 0x00: '00' |
|
204 | + 0x01: '01' |
|
205 | + 0x02: '02' |
|
206 | + 0x04: '04' |
|
207 | + 0x08: '08' |
|
208 | + 0x0a: 0a |
|
209 | + 0x10: 10 |
|
210 | +Hexadecimal: |
|
211 | + - 0x00 |
|
212 | + - 0x01 |
|
213 | + - 0x02 |
|
214 | + - 0x04 |
|
215 | + - 0x08 |
|
216 | + - 0x0a |
|
217 | + - 0x10 |
|
218 | +Octal: |
|
219 | + - '000' |
|
220 | + - '001' |
|
221 | + - '002' |
|
222 | + - '004' |
|
223 | + - '010' |
|
224 | + - '012' |
|
225 | + - '020' |
|
226 | +漢字: |
|
227 | + - 壱 |
|
228 | + - 弐 |
|
229 | + - 参 |
|
230 | + - 四 |
|
231 | + - 五 |
|
232 | + |
|
233 | +$YAML::Syck::ImplicitTyping = 1 |
|
234 | +--- |
|
235 | +Binal: |
|
236 | + - 0b00000 |
|
237 | + - 0b00001 |
|
238 | + - 0b00010 |
|
239 | + - 0b00100 |
|
240 | + - 0b01000 |
|
241 | + - 0b01010 |
|
242 | + - 0b10000 |
|
243 | +Boolean: |
|
244 | + - 1 |
|
245 | + - '' |
|
246 | + - 1 |
|
247 | + - '' |
|
248 | + - 1 |
|
249 | + - '' |
|
250 | + - ~ |
|
251 | + - ~ |
|
252 | +Decimal: |
|
253 | + - 0 |
|
254 | + - 1 |
|
255 | + - 2 |
|
256 | + - 4 |
|
257 | + - 8 |
|
258 | + - 10 |
|
259 | + - 16 |
|
260 | +HexKey: |
|
261 | + 0: '00' |
|
262 | + 1: '01' |
|
263 | + 10: 0a |
|
264 | + 16: 10 |
|
265 | + 2: '02' |
|
266 | + 4: '04' |
|
267 | + 8: '08' |
|
268 | +Hexadecimal: |
|
269 | + - 0 |
|
270 | + - 1 |
|
271 | + - 2 |
|
272 | + - 4 |
|
273 | + - 8 |
|
274 | + - 10 |
|
275 | + - 16 |
|
276 | +Octal: |
|
277 | + - 0 |
|
278 | + - 1 |
|
279 | + - 2 |
|
280 | + - 4 |
|
281 | + - 8 |
|
282 | + - 10 |
|
283 | + - 16 |
|
284 | +漢字: |
|
285 | + - 壱 |
|
286 | + - 弐 |
|
287 | + - 参 |
|
288 | + - 四 |
|
289 | + - 五 |
|
290 | +``` |
|
291 | + |
|
292 | +# 正規表現 |
|
293 | + |
|
294 | +## 概要 |
|
295 | +- YAML 中での正規表現の表記方法。 |
|
296 | +- YAML::Syck で Dump すると、非 ASCII 文字列はバイト列となる。 |
|
297 | +- バイト列を Load しても utf8 フラグが失われているため、ユニコード文字列にはマッチしない。 |
|
298 | +- 正規表現中にユニコード文字を入れたい場合は、\x{xxxx} または \N{U+xxxx} と表記しなければならない。 |
|
299 | +- 正規表現の文字列化 ([perl v5.14.0 での変更点](http://perldoc.jp/docs/perl/5.14.0/perl5140delta.pod#Regular32Expressions)) |
|
300 | + - perl 5.14 以降: (?^:...) |
|
301 | + - perl 5.14 前: (?-xism:...) |
|
302 | + |
|
303 | +## ソース |
|
304 | +- [RegExp.zip](RegExp.zip) |
|
305 | +```perl |
|
306 | +#!/usr/bin/perl |
|
307 | +# 正規表現の読み込み |
|
308 | + |
|
309 | +use strict; |
|
310 | +use warnings; |
|
311 | +use utf8; |
|
312 | +use Encode; |
|
313 | +use YAML::Syck qw( Load Dump ); |
|
314 | +use Win32::Unicode::Native; |
|
315 | + |
|
316 | +$YAML::Syck::ImplicitUnicode = 1; |
|
317 | + |
|
318 | +# バージョン確認 |
|
319 | +print "Perl version: $]\n"; |
|
320 | +print "YAML::Syck version: $YAML::Syck::VERSION\n"; |
|
321 | + |
|
322 | +my $obj = { |
|
323 | + '\[AD\]$' => qr/\[AD\]$/i, |
|
324 | + '\[広\s?告\]$' => qr/\[広\s?告\]$/, |
|
325 | + '(吉|\x{20bb7})野' => qr/(吉|\x{20bb7})野/, |
|
326 | +}; |
|
327 | +my $yaml = Dump( $obj ); |
|
328 | +print $yaml; |
|
329 | +my $yaml2 = q{ |
|
330 | +--- |
|
331 | +'\[AD\]$': |
|
332 | + !!perl/regexp (?^i:\[AD\]$) |
|
333 | +'\[広\s?告\]$': |
|
334 | + !!perl/regexp (?^:\[\x{5e83}\s?\x{544a}\]$) |
|
335 | +'(吉|\x{20bb7})野': |
|
336 | + !!perl/regexp (?^:(\x{5409}|\x{20bb7})\x{91ce}) |
|
337 | +}; |
|
338 | +print $yaml2; |
|
339 | +my $conf = Load($yaml2); |
|
340 | +print Dump($conf); |
|
341 | + |
|
342 | +print "====\n"; |
|
343 | + |
|
344 | +my @samples = ( |
|
345 | + "無料で始める恋愛ドラマアプリ[広 告]", |
|
346 | + "この夏をもっと楽しもう[Ad]", |
|
347 | + "\x{20BB7}野家", |
|
348 | +); |
|
349 | + |
|
350 | +foreach my $sample (@samples){ |
|
351 | + my $isMatch = ''; |
|
352 | + foreach my $regex (keys(%{$conf})){ |
|
353 | + if ( $sample =~ $conf->{$regex} ){ |
|
354 | + $isMatch = $regex; |
|
355 | + last; |
|
356 | + } |
|
357 | + } |
|
358 | + if ( $isMatch ){ |
|
359 | + printf("match(%s): '%s'\n", $isMatch, $sample); |
|
360 | + } else { |
|
361 | + printf("not match: '%s'\n", $sample); |
|
362 | + } |
|
363 | +} |
|
364 | + |
|
365 | +# EOF |
|
366 | +``` |
|
367 | + |
|
368 | +## 出力結果 |
|
369 | +``` |
|
370 | +Perl version: 5.014004 |
|
371 | +YAML::Syck version: 1.22 |
|
372 | +--- |
|
373 | +"(吉|\\x{20bb7})野": !!perl/regexp "(?^u:(\xE5\x90\x89|\\x{20bb7})\xE9\x87\x8E)" |
|
374 | + |
|
375 | +\[AD\]$: !!perl/regexp (?^i:\[AD\]$) |
|
376 | +"\\[広\\s?告\\]$": !!perl/regexp "(?^u:\\[\xE5\xBA\x83\\s?\xE5\x91\x8A\\]$)" |
|
377 | + |
|
378 | +--- |
|
379 | +'\[AD\]$': |
|
380 | + !!perl/regexp (?^i:\[AD\]$) |
|
381 | +'\[広\s?告\]$': |
|
382 | + !!perl/regexp (?^:\[\x{5e83}\s?\x{544a}\]$) |
|
383 | +'(吉|\x{20bb7})野': |
|
384 | + !!perl/regexp (?^:(\x{5409}|\x{20bb7})\x{91ce}) |
|
385 | +--- |
|
386 | +"(吉|\\x{20bb7})野": !!perl/regexp (?^u:(?^:(\x{5409}|\x{20bb7})\x{91ce})) |
|
387 | +\[AD\]$: !!perl/regexp (?^:(?^i:\[AD\]$)) |
|
388 | +"\\[広\\s?告\\]$": !!perl/regexp (?^u:(?^:\[\x{5e83}\s?\x{544a}\]$)) |
|
389 | +==== |
|
390 | +match(\[広\s?告\]$): '無料で始める恋愛ドラマアプリ[広 告]' |
|
391 | +match(\[AD\]$): 'この夏をもっと楽しもう[Ad]' |
|
392 | +match((吉|\x{20bb7})野): '𠮷野家' |
|
393 | +``` |
|
394 | + |
|
395 | +# リンク |
|
396 | +- http://yaml.org/ / [仕様](http://yaml.org/spec/current.html) |
|
397 | +- [CPAN:YAML-Syck](http://search.cpan.org/dist/YAML-Syck) |
|
398 | +- [Rubyist Magazine - プログラマーのための YAML 入門 (初級編)](http://jp.rubyist.net/magazine/?0009-YAML) |
|
399 | + |
|
400 | +- [CPAN:Config-IniFiles](http://search.cpan.org/dist/Config-IniFiles) |
|
... | ... | \ No newline at end of file |
Perl/compareXML.md
... | ... | @@ -0,0 +1,378 @@ |
1 | +# XMLファイルを比較 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- XMLファイルを比較し、要素/属性が一致する場合は「=:」、不一致の場合は行頭に「!」を付けて表示します。 |
|
6 | +- 他方に項目が無かった場合は「~」が表示されます。 |
|
7 | +- XMLの要素も属性も共に配列ではなくハッシュとして取り扱います。 |
|
8 | +- 設定を外部ファイルから読み込むようにしました。(2012/05/20) |
|
9 | + - Settings.yml では、PARAM要素を、NAME属性をキー、VALUE属性を値とするハッシュに変換します。 |
|
10 | +- 3つ以上のXMLファイルも比較できるようにしました。(2012/05/20) |
|
11 | +- 初版(2012/05/18) |
|
12 | + |
|
13 | +## ソース |
|
14 | +- [compareXML.zip](compareXML.zip) |
|
15 | + |
|
16 | +## compareXML.pl |
|
17 | +```perl |
|
18 | +# XMLファイルを比較 |
|
19 | + |
|
20 | +use strict; |
|
21 | +use warnings; |
|
22 | +use utf8; |
|
23 | +use Encode; |
|
24 | +use XML::Simple; |
|
25 | +use YAML::Syck; |
|
26 | +use Getopt::Long; |
|
27 | + |
|
28 | +$YAML::Syck::ImplicitUnicode = 1; |
|
29 | + |
|
30 | +my $charsetConsole = 'CP932'; |
|
31 | +my $charsetFile = 'UTF-8'; |
|
32 | + |
|
33 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
34 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
35 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
36 | + |
|
37 | +my $configFile = ""; |
|
38 | +my $config = { |
|
39 | + 'Output' => "diff.txt", |
|
40 | + 'Indent' => "\t", |
|
41 | + 'XMLOpt' => {}, |
|
42 | +}; |
|
43 | +my @FileNames = (); |
|
44 | +my $root = {}; |
|
45 | + |
|
46 | +@ARGV = map{ decode( $charsetConsole, $_ ); } @ARGV; |
|
47 | + |
|
48 | +my $result = GetOptions( |
|
49 | + "config=s" => \$configFile, |
|
50 | +); |
|
51 | + |
|
52 | +if ( @ARGV < 2 ){ |
|
53 | + die( "usage: compareXML [-config <yml>] <xml> <xml> [<xml> ...]\n" ); |
|
54 | +} |
|
55 | + |
|
56 | +if ( $configFile ){ |
|
57 | + my $config2 = YAML::Syck::LoadFile( encode( $charsetConsole, $configFile ) ) |
|
58 | + or die( "$configFile: $!\n" ); |
|
59 | + $config = { %{$config}, %{$config2} }; |
|
60 | +} |
|
61 | +my $fileOut = $config->{'Output'}; |
|
62 | +my $IndentBase = $config->{'Indent'}; |
|
63 | + |
|
64 | +my $xs = XML::Simple->new( %{$config->{'XMLOpt'}} ); |
|
65 | + |
|
66 | +foreach my $file ( @ARGV ){ |
|
67 | + if ( -f encode( $charsetConsole, $file ) ){ |
|
68 | + push( @FileNames, $file ); |
|
69 | + $root->{$file} = $xs->XMLin( encode( $charsetConsole, $file ) ); |
|
70 | + } else { |
|
71 | + die( "Not exist: $file\n" ); |
|
72 | + } |
|
73 | +} |
|
74 | + |
|
75 | +open( my $fhout, ">:encoding($charsetFile)", encode( $charsetConsole, $fileOut ) ) |
|
76 | + or die( "$fileOut: $!" ); |
|
77 | + |
|
78 | +#print $fhout Dump( $xml ); |
|
79 | +compareNodes( $root, 0 ); |
|
80 | + |
|
81 | +close( $fhout ); |
|
82 | + |
|
83 | +sub compareNodes |
|
84 | +{ |
|
85 | + my( $href, $indent ) = @_; |
|
86 | + my $IndentText1 = $IndentBase x $indent; |
|
87 | + my $IndentText2 = $IndentBase x ( $indent + 1 ); |
|
88 | + |
|
89 | + # すべてのキーを列挙 |
|
90 | + my %currentkeys = (); |
|
91 | + foreach my $fn ( @FileNames ){ |
|
92 | + if ( ref( $href->{$fn} ) eq 'HASH' ){ |
|
93 | + foreach my $key ( keys( %{$href->{$fn}} ) ){ |
|
94 | + $currentkeys{$key} = 1; |
|
95 | + } |
|
96 | + } |
|
97 | + } |
|
98 | + foreach my $key ( sort( keys( %currentkeys ) ) ){ |
|
99 | + printf $fhout ( "%s%s:\n", $IndentText1, $key ); |
|
100 | + my $bHash = 0; # どちらかがハッシュなら1 |
|
101 | + my $child = {}; |
|
102 | + foreach my $fn ( @FileNames ){ |
|
103 | + if ( ref( $href->{$fn} ) eq 'HASH' ){ |
|
104 | + my $t1 = $href->{$fn}{$key} // '~'; # undef は '~' |
|
105 | + $child->{$fn} = $t1; |
|
106 | + if ( ref( $t1 ) eq 'HASH' ){ |
|
107 | + $bHash = 1; |
|
108 | + } |
|
109 | + } else { |
|
110 | + $child->{$fn} = '~'; |
|
111 | + } |
|
112 | + } |
|
113 | + if ( $bHash ){ |
|
114 | + # どちらかがハッシュの場合は再帰探索 |
|
115 | + compareNodes( $child, $indent + 1 ); |
|
116 | + } else { |
|
117 | + # 両方共ハッシュでなければ値の表示 |
|
118 | + if ( eqAll( $child ) ){ |
|
119 | + # 一致する場合は「=:」でまとめて表示 |
|
120 | + printf $fhout ( |
|
121 | + "%s=:%s%s\n", |
|
122 | + $IndentText2, $IndentBase, $child->{$FileNames[0]} |
|
123 | + ); |
|
124 | + } else { |
|
125 | + # 不一致の場合は行頭に「!」を付けて表示 |
|
126 | + foreach my $fn ( @FileNames ){ |
|
127 | + printf $fhout ( |
|
128 | + "!%s%s:%s%s\n", |
|
129 | + $IndentText2, $fn, $IndentBase, $child->{$fn} |
|
130 | + ); |
|
131 | + } |
|
132 | + } |
|
133 | + } |
|
134 | + } |
|
135 | +} |
|
136 | + |
|
137 | +## @function eqAll( %$refHash ) |
|
138 | +# ハッシュの全ての値を比較する。 |
|
139 | +# @retval 一致 1 |
|
140 | +# @retval 不一致 0 |
|
141 | +sub eqAll |
|
142 | +{ |
|
143 | + my( $refHash ) = @_; |
|
144 | + my $bEqual = 1; |
|
145 | + my @Keys = keys( %{$refHash} ); |
|
146 | + my $first = $refHash->{ shift( @Keys ) }; |
|
147 | + foreach my $key ( @Keys ){ |
|
148 | + if ( $first ne $refHash->{ $key } ){ |
|
149 | + $bEqual = 0; |
|
150 | + last; |
|
151 | + } |
|
152 | + } |
|
153 | + return $bEqual; |
|
154 | +} |
|
155 | + |
|
156 | +# EOF |
|
157 | +``` |
|
158 | + |
|
159 | +## 入力 |
|
160 | +### Settings.yml |
|
161 | +``` |
|
162 | +Output: diff.txt |
|
163 | +Indent: "\t" |
|
164 | + |
|
165 | +XMLOpt: |
|
166 | + ForceArray: |
|
167 | + - PARAM |
|
168 | + KeyAttr: |
|
169 | + PARAM: NAME |
|
170 | + OPERATION: NAME |
|
171 | + ContentKey: |
|
172 | + "-VALUE" |
|
173 | +``` |
|
174 | + |
|
175 | +### Item1.xml |
|
176 | +``` |
|
177 | +<SETTINGS NAME="Item1" VERSION="8" > |
|
178 | + <DOCUMENT DOCUMENT_ID="79" NAME="Doc02.indd" SRC="//localhost/Data/2/2/" TYPE="INDD" /> |
|
179 | + <OUTPUT> |
|
180 | + <PARAM NAME="START_RECORD" VALUE="1" /> |
|
181 | + <PARAM NAME="END_RECORD" VALUE="100" /> |
|
182 | + <PARAM NAME="TYPE" VALUE="PDF" /> |
|
183 | + <PARAM NAME="CENTER_PAGE" VALUE="0" /> |
|
184 | + </OUTPUT> |
|
185 | + <ASSET_LIST Resolve="1"> |
|
186 | + <ASSET ID="73" NAME="Assets1" PRIORITY="1" TYPE="LOCAL" > |
|
187 | + <PARAM NAME="BaseID" VALUE="1" /> |
|
188 | + </ASSET> |
|
189 | + </ASSET_LIST> |
|
190 | + <DATA_SOURCES> |
|
191 | + <DATA_SOURCE ID="13" > |
|
192 | + <PARAM NAME="FILENAME" VALUE="db1.csv" /> |
|
193 | + <PARAM NAME="TYPE" VALUE="TEXT" /> |
|
194 | + </DATA_SOURCE> |
|
195 | + </DATA_SOURCES> |
|
196 | + <FONT_LIST> |
|
197 | + <FONT ID="20" NAME="Arial" OPTION="OpenType" /> |
|
198 | + </FONT_LIST> |
|
199 | + <POST_PRODUCTION /> |
|
200 | +</SETTINGS> |
|
201 | +``` |
|
202 | + |
|
203 | +### Item2.xml |
|
204 | +``` |
|
205 | +<SETTINGS NAME="Item2" VERSION="8" > |
|
206 | + <DOCUMENT DOCUMENT_ID="78" NAME="Doc01.indd" SRC="//localhost/Data/2/1/" TYPE="INDD" /> |
|
207 | + <ASSET_LIST Resolve="1"> |
|
208 | + <ASSET ID="73" NAME="Assets1" PRIORITY="1" TYPE="LOCAL" > |
|
209 | + <PARAM NAME="BaseID" VALUE="1" /> |
|
210 | + </ASSET> |
|
211 | + </ASSET_LIST> |
|
212 | + <JOB ID="330" TYPE="PRINT"> |
|
213 | + <PARAM NAME="HOST_NAME" VALUE="localhost" /> |
|
214 | + <JOB_CONTEXT JobID="330" JobName="Doc01" JobType="1" /> |
|
215 | + </JOB> |
|
216 | + <OUTPUT MEDIA="1" OUTPUT_FILE_NAME="Doc01" TYPE="PDF"> |
|
217 | + <PARAM NAME="TYPE" VALUE="PDF" /> |
|
218 | + <PARAM NAME="START_RECORD" VALUE="80" /> |
|
219 | + <PARAM NAME="END_RECORD" VALUE="100" /> |
|
220 | + <PARAM NAME="FONTS_POLICY" VALUE="1" /> |
|
221 | + <PARAM NAME="OVERFLOW_POLICY" VALUE="0" /> |
|
222 | + </OUTPUT> |
|
223 | + <FONT_LIST> |
|
224 | + <FONT ID="20" NAME="Arial" /> |
|
225 | + </FONT_LIST> |
|
226 | + <POST_PRODUCTION JOBID="330"> |
|
227 | + <OPERATION NAME="IMPOSITION"> |
|
228 | + <PARAM NAME="NUPX" VALUE="1" /> |
|
229 | + <PARAM NAME="NUPY" VALUE="2" /> |
|
230 | + </OPERATION> |
|
231 | + <OPERATION NAME="DISTILLER"> |
|
232 | + <PARAM NAME="DSTL_SETTINGS" VALUE="HighQuality" /> |
|
233 | + </OPERATION> |
|
234 | + <OPERATION NAME="COPY"> |
|
235 | + <PARAM NAME="DEST_PATH" VALUE="//localhost/Output/2/1/" /> |
|
236 | + </OPERATION> |
|
237 | + </POST_PRODUCTION> |
|
238 | + <TRACK_INFO /> |
|
239 | +</SETTINGS> |
|
240 | +``` |
|
241 | + |
|
242 | +## 出力 |
|
243 | +``` |
|
244 | +ASSET_LIST: |
|
245 | + ASSET: |
|
246 | + ID: |
|
247 | + =: 73 |
|
248 | + NAME: |
|
249 | + =: Assets1 |
|
250 | + PARAM: |
|
251 | + BaseID: |
|
252 | + =: 1 |
|
253 | + PRIORITY: |
|
254 | + =: 1 |
|
255 | + TYPE: |
|
256 | + =: LOCAL |
|
257 | + Resolve: |
|
258 | + =: 1 |
|
259 | +DATA_SOURCES: |
|
260 | + DATA_SOURCE: |
|
261 | + ID: |
|
262 | +! Item1.xml: 13 |
|
263 | +! Item2.xml: ~ |
|
264 | + PARAM: |
|
265 | + FILENAME: |
|
266 | +! Item1.xml: db1.csv |
|
267 | +! Item2.xml: ~ |
|
268 | + TYPE: |
|
269 | +! Item1.xml: TEXT |
|
270 | +! Item2.xml: ~ |
|
271 | +DOCUMENT: |
|
272 | + DOCUMENT_ID: |
|
273 | +! Item1.xml: 79 |
|
274 | +! Item2.xml: 78 |
|
275 | + NAME: |
|
276 | +! Item1.xml: Doc02.indd |
|
277 | +! Item2.xml: Doc01.indd |
|
278 | + SRC: |
|
279 | +! Item1.xml: //localhost/Data/2/2/ |
|
280 | +! Item2.xml: //localhost/Data/2/1/ |
|
281 | + TYPE: |
|
282 | + =: INDD |
|
283 | +FONT_LIST: |
|
284 | + FONT: |
|
285 | + ID: |
|
286 | + =: 20 |
|
287 | + NAME: |
|
288 | + =: Arial |
|
289 | + OPTION: |
|
290 | +! Item1.xml: OpenType |
|
291 | +! Item2.xml: ~ |
|
292 | +JOB: |
|
293 | + ID: |
|
294 | +! Item1.xml: ~ |
|
295 | +! Item2.xml: 330 |
|
296 | + JOB_CONTEXT: |
|
297 | + JobID: |
|
298 | +! Item1.xml: ~ |
|
299 | +! Item2.xml: 330 |
|
300 | + JobName: |
|
301 | +! Item1.xml: ~ |
|
302 | +! Item2.xml: Doc01 |
|
303 | + JobType: |
|
304 | +! Item1.xml: ~ |
|
305 | +! Item2.xml: 1 |
|
306 | + PARAM: |
|
307 | + HOST_NAME: |
|
308 | +! Item1.xml: ~ |
|
309 | +! Item2.xml: localhost |
|
310 | + TYPE: |
|
311 | +! Item1.xml: ~ |
|
312 | +! Item2.xml: PRINT |
|
313 | +NAME: |
|
314 | +! Item1.xml: Item1 |
|
315 | +! Item2.xml: Item2 |
|
316 | +OUTPUT: |
|
317 | + MEDIA: |
|
318 | +! Item1.xml: ~ |
|
319 | +! Item2.xml: 1 |
|
320 | + OUTPUT_FILE_NAME: |
|
321 | +! Item1.xml: ~ |
|
322 | +! Item2.xml: Doc01 |
|
323 | + PARAM: |
|
324 | + CENTER_PAGE: |
|
325 | +! Item1.xml: 0 |
|
326 | +! Item2.xml: ~ |
|
327 | + END_RECORD: |
|
328 | + =: 100 |
|
329 | + FONTS_POLICY: |
|
330 | +! Item1.xml: ~ |
|
331 | +! Item2.xml: 1 |
|
332 | + OVERFLOW_POLICY: |
|
333 | +! Item1.xml: ~ |
|
334 | +! Item2.xml: 0 |
|
335 | + START_RECORD: |
|
336 | +! Item1.xml: 1 |
|
337 | +! Item2.xml: 80 |
|
338 | + TYPE: |
|
339 | + =: PDF |
|
340 | + TYPE: |
|
341 | +! Item1.xml: ~ |
|
342 | +! Item2.xml: PDF |
|
343 | +POST_PRODUCTION: |
|
344 | + JOBID: |
|
345 | +! Item1.xml: ~ |
|
346 | +! Item2.xml: 330 |
|
347 | + OPERATION: |
|
348 | + COPY: |
|
349 | + PARAM: |
|
350 | + DEST_PATH: |
|
351 | +! Item1.xml: ~ |
|
352 | +! Item2.xml: //localhost/Output/2/1/ |
|
353 | + DISTILLER: |
|
354 | + PARAM: |
|
355 | + DSTL_SETTINGS: |
|
356 | +! Item1.xml: ~ |
|
357 | +! Item2.xml: HighQuality |
|
358 | + IMPOSITION: |
|
359 | + PARAM: |
|
360 | + NUPX: |
|
361 | +! Item1.xml: ~ |
|
362 | +! Item2.xml: 1 |
|
363 | + NUPY: |
|
364 | +! Item1.xml: ~ |
|
365 | +! Item2.xml: 2 |
|
366 | +TRACK_INFO: |
|
367 | +VERSION: |
|
368 | + =: 8 |
|
369 | +``` |
|
370 | + |
|
371 | +## Link |
|
372 | +- Perl/XML-Simple |
|
373 | + |
|
374 | +- [CPAN:XML-Simple](http://search.cpan.org/dist/XML-Simple) |
|
375 | +- [CPAN:Getopt-Long](http://search.cpan.org/dist/Getopt-Long) |
|
376 | + |
|
377 | +- [XML Notepad](http://www.microsoft.com/en-us/download/details.aspx?id=7973) XmlDiff機能あり |
|
378 | +- [diffxml](http://diffxml.sourceforge.net/) XML Diff and Patch Utilities |
|
... | ... | \ No newline at end of file |
Perl/createUniqKeyList.md
... | ... | @@ -0,0 +1,86 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- 重複のないランダムなキーの一群を作る。 |
|
5 | +- キーの長さと使用可能文字数が、キーの個数に対して十分かどうかチェック。(2007/06/18) |
|
6 | +- Text::CSV_XS, Win32::Unicode::Native を使用するようにした。(2013/06/07) |
|
7 | + |
|
8 | +# ソース |
|
9 | +- [createUniqKeyList.zip](createUniqKeyList.zip) |
|
10 | +```perl |
|
11 | +# ユニークキー作成スクリプト |
|
12 | +# by take-ash |
|
13 | +# 2013.06.07 |
|
14 | +# |
|
15 | +# 重複のないランダムなキーの一群を作る。 |
|
16 | + |
|
17 | +use strict; |
|
18 | +use warnings; |
|
19 | +use utf8; |
|
20 | +use Encode; |
|
21 | +use Text::CSV_XS; |
|
22 | +use Win32::Unicode::Native; |
|
23 | + |
|
24 | +my $charsetFile = 'UTF-8'; |
|
25 | + |
|
26 | +my $fileNameOut = 'uniqueKeys.txt'; # 出力ファイル名。 |
|
27 | +my $keyLength = 6; # キーの長さ |
|
28 | +my $keyMax = 50; # キーの個数 |
|
29 | +my $possibleChar = # 使用可能文字 |
|
30 | +# 'あいうえお' . |
|
31 | + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . |
|
32 | + 'abcdefghijklmnopqrstuvwxyz' . |
|
33 | + '0123456789'; |
|
34 | +my $keyCharMax = length( $possibleChar ); |
|
35 | + |
|
36 | +if ( ( $keyCharMax ** $keyLength ) < $keyMax ){ |
|
37 | + die( "Too short KeyLength or Too few PossibleChar against KeyMax.\n" ); |
|
38 | +} |
|
39 | + |
|
40 | +my %keyPool = (); |
|
41 | +my @keyList = ( [ 'ID', 'Key' ] ); |
|
42 | + |
|
43 | +srand( time ); |
|
44 | + |
|
45 | +$| = 1; |
|
46 | + |
|
47 | +for( my $i=1; $i <= $keyMax; ++$i ){ |
|
48 | + printf( "%d/%d\r", $i, $keyMax ); |
|
49 | + my $tmpKey = makeNewKey(); |
|
50 | + while( $keyPool{ $tmpKey } ){ |
|
51 | + $tmpKey = makeNewKey(); |
|
52 | + } |
|
53 | + $keyPool{ $tmpKey } = 1; |
|
54 | + push( @keyList, [ $i, $tmpKey ] ); |
|
55 | +} |
|
56 | +print "\n"; |
|
57 | +$| = 0; |
|
58 | + |
|
59 | +my $csv = Text::CSV_XS->new({ binary => 1, sep_char => "\t", eol => $/ }); |
|
60 | +open( my $OUT, ">:encoding($charsetFile)", $fileNameOut ) |
|
61 | + or die( "$fileNameOut: $!\n" ); |
|
62 | +foreach my $row ( @keyList ){ |
|
63 | + $csv->print( $OUT, $row ); |
|
64 | +} |
|
65 | +close( $OUT ); |
|
66 | + |
|
67 | +exit; |
|
68 | + |
|
69 | +sub makeNewKey { |
|
70 | + my $result = ''; |
|
71 | + |
|
72 | + while( length( $result ) < $keyLength ){ |
|
73 | + $result .= substr( $possibleChar, int( rand( $keyCharMax ) ), 1 ); |
|
74 | + } |
|
75 | + |
|
76 | + return $result; |
|
77 | +} |
|
78 | + |
|
79 | +# EOF |
|
80 | +``` |
|
81 | + |
|
82 | +# リンク |
|
83 | +- [[Perl/readXSV]] |
|
84 | + |
|
85 | +- [CPAN:Text-CSV_XS](http://search.cpan.org/dist/Text-CSV_XS) |
|
86 | +- [CPAN:Win32-Unicode](http://search.cpan.org/dist/Win32-Unicode) |
|
... | ... | \ No newline at end of file |
Perl/decodeQuotedPrintable.md
... | ... | @@ -0,0 +1,58 @@ |
1 | +# Quoted Printableのデコード |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- ファイルとして保存された Quoted Printable をデコードする。 |
|
6 | +- デコードされたファイルの名前は元のファイル名に「.html」を付けたものになる。 |
|
7 | +- 既存ファイルは問い合わせなしに上書きされる。 |
|
8 | +- 対象のファイルを選択し、コンテキストメニューの「送る」(SendTo) からスクリプトを呼び出す。 |
|
9 | +- スクリプトへのショートカットのリンク先には「%1」を付けてはいけない。 |
|
10 | +``` |
|
11 | +C:\Perl\bin\perl.exe "D:\myscripts\decodeQuotedPrintable.pl" |
|
12 | +``` |
|
13 | + |
|
14 | +## ソース |
|
15 | +- [decodeQuotedPrintable.zip](decodeQuotedPrintable.zip) |
|
16 | +``` |
|
17 | +# quoted-printable のデコード |
|
18 | + |
|
19 | +use strict; |
|
20 | +use warnings; |
|
21 | +use utf8; |
|
22 | +use Encode; |
|
23 | +use MIME::QuotedPrint; |
|
24 | +use Term::ReadKey; |
|
25 | + |
|
26 | +my $charset = 'CP932'; |
|
27 | + |
|
28 | +binmode( STDIN, ":encoding($charset)" ); |
|
29 | +binmode( STDOUT, ":encoding($charset)" ); |
|
30 | +binmode( STDERR, ":encoding($charset)" ); |
|
31 | + |
|
32 | +@ARGV = map{ decode( $charset, $_ ); } @ARGV; |
|
33 | + |
|
34 | +foreach my $fileNameIn ( @ARGV ){ |
|
35 | + warn( "$fileNameIn\n" ); |
|
36 | + my $fileNameOut = $fileNameIn . '.html'; |
|
37 | + |
|
38 | + open( my $fin, "<:utf8", encode( $charset, $fileNameIn ) ) or die( "$fileNameIn: $!\n" ); |
|
39 | + my @lines = <$fin>; |
|
40 | + close( $fin ); |
|
41 | + my $body = join( '', @lines ); |
|
42 | + |
|
43 | + $body = decode_qp( $body ); |
|
44 | + |
|
45 | + open( my $fout, ">:utf8", encode( $charset, $fileNameOut ) ) or die( "$fileNameOut: $!\n" ); |
|
46 | + print $fout $body; |
|
47 | + close( $fout ); |
|
48 | +} |
|
49 | + |
|
50 | +warn( "Hit Enter.\n" ); |
|
51 | +ReadKey(0); |
|
52 | + |
|
53 | +# EOF |
|
54 | +``` |
|
55 | + |
|
56 | +## リンク |
|
57 | +- [CPAN:MIME-Base64](http://search.cpan.org/dist/MIME-Base64) |
|
58 | +- [CPAN:TermReadKey](http://search.cpan.org/dist/TermReadKey) |
|
... | ... | \ No newline at end of file |
Perl/getDiskUsage.md
... | ... | @@ -0,0 +1,55 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- 指定したパスを含むパーティションの使用容量(%)を調べる。 |
|
5 | + |
|
6 | +# Filesys::Df 版 |
|
7 | +- 使用パーセントは「per」で得られる。 |
|
8 | + |
|
9 | +## ソース |
|
10 | +- [getDiskUsage.zip](getDiskUsage.zip) |
|
11 | +```perl |
|
12 | +#!/usr/bin/perl |
|
13 | +# 指定したパスを含むパーティションの使用状況を調べる。 |
|
14 | + |
|
15 | +use strict; |
|
16 | +use warnings; |
|
17 | +use utf8; |
|
18 | +use Filesys::Df; |
|
19 | +use Number::Format qw(:subs); |
|
20 | + |
|
21 | +my $path = shift or die("usage: getDiskUsage <path>\n"); |
|
22 | +my $refDf = df($path, 1) or die("$!\n"); |
|
23 | +foreach my $key (sort(keys(%{$refDf}))){ |
|
24 | + print $key . ":\t" . format_bytes($refDf->{$key}) . "\n"; |
|
25 | +} |
|
26 | + |
|
27 | +# EOF |
|
28 | +``` |
|
29 | + |
|
30 | +# 自前版 |
|
31 | +- OSコマンド・インジェクション対策はしてないので、安全なパスのみ渡すようにすること。 |
|
32 | +- エラー時には「-1」が戻る。 |
|
33 | + |
|
34 | +## ソース |
|
35 | +```perl |
|
36 | +sub getDiskUsage |
|
37 | +{ |
|
38 | + my $path = shift || '/'; |
|
39 | + my $result = `df -h $path`; |
|
40 | + $result =~ /(\d+)%\s+\//; |
|
41 | + return $1 || -1; |
|
42 | +} |
|
43 | +``` |
|
44 | + |
|
45 | +# リンク |
|
46 | +- [CPAN:Filesys-Df](http://search.cpan.org/dist/Filesys-Df) |
|
47 | +- [CPAN:Filesys-DfPortable](http://search.cpan.org/dist/Filesys-DfPortable) |
|
48 | +- [CPAN:Number-Format](http://search.cpan.org/dist/Number-Format) |
|
49 | + |
|
50 | +- [IPA セキュア・プログラミング講座:Webアプリケーション編](http://www.ipa.go.jp/security/awareness/vendor/programmingv2/web.html) |
|
51 | + - [第6章 入力対策:コマンド注入攻撃対策](http://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/501.html) |
|
52 | +- [安全なウェブサイトの作り方:IPA](http://www.ipa.go.jp/security/vuln/websecurity.html) |
|
53 | + |
|
54 | +- [Linuxコマンド集 - 【 df 】 ディスク・ドライブの使用量を表示する:ITpro](http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230742/) |
|
55 | +- [Linuxコマンド集 - 【 du 】 ディレクトリ内のファイル容量を表示する:ITpro](http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230748/) |
|
... | ... | \ No newline at end of file |
Perl/getHostName.md
... | ... | @@ -0,0 +1,54 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- IPアドレスからホスト名を逆引きする。 |
|
5 | +- IPv6 対応。 |
|
6 | + |
|
7 | +# ソース |
|
8 | +- [getHostName.zip](getHostName.zip) |
|
9 | +```perl |
|
10 | +#!/usr/bin/perl |
|
11 | +# ホスト名逆引き(IPv6にも対応) |
|
12 | +# http://www.alib.jp/perl/resolv.html |
|
13 | + |
|
14 | +use strict; |
|
15 | +use warnings; |
|
16 | +use utf8; |
|
17 | +use Encode; |
|
18 | +use Net::DNS::Resolver; |
|
19 | + |
|
20 | +my $ip = $ARGV[0] || ''; |
|
21 | +my $name = getHostName( $ip ); |
|
22 | +print "IP:\t${ip}\nHost:\t${name}\n"; |
|
23 | + |
|
24 | +sub getHostName |
|
25 | +{ |
|
26 | + my $ip_address = shift || ''; |
|
27 | + my $ret = ''; |
|
28 | + |
|
29 | + my $resolver = Net::DNS::Resolver->new; |
|
30 | + if ( my $ans = $resolver->query( $ip_address ) ){ |
|
31 | + for my $rr ( $ans->answer ){ |
|
32 | + #print $rr->string, "\n"; |
|
33 | + if ( $rr->type eq 'PTR' ){ |
|
34 | + $ret = $rr->ptrdname; |
|
35 | + last; |
|
36 | + } |
|
37 | + } |
|
38 | + } |
|
39 | + |
|
40 | + return $ret; |
|
41 | +} |
|
42 | + |
|
43 | +# EOF |
|
44 | +``` |
|
45 | + |
|
46 | +# リンク |
|
47 | +- [[Perl/HostToIP]] |
|
48 | + |
|
49 | +- [CPAN:Net-DNS](http://search.cpan.org/dist/Net-DNS) |
|
50 | + - [CPAN:Net-DNS/lib/Net/DNS/Resolver.pm](http://search.cpan.org/dist/Net-DNS/lib/Net/DNS/Resolver.pm) |
|
51 | + - [CPAN:Net-DNS/lib/Net/DNS/RR.pm](http://search.cpan.org/dist/Net-DNS/lib/Net/DNS/RR.pm) |
|
52 | + |
|
53 | +- [Ancient library](http://www.alib.jp/) |
|
54 | + - [IPv4/IPv6 アドレスから、ホスト名を取得する](http://www.alib.jp/perl/resolv.html) |
|
... | ... | \ No newline at end of file |
Perl/initConsole.md
... | ... | @@ -0,0 +1,49 @@ |
1 | +# initConsole |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- Linux/Windows共通に環境変数からコンソールの文字コードとホームディレクトリを設定する。 |
|
6 | + |
|
7 | +## ソース |
|
8 | +- [initConsole.zip](initConsole.zip) |
|
9 | + |
|
10 | +### initConsole.pl |
|
11 | +```perl |
|
12 | +#!/usr/bin/perl |
|
13 | +# Linux/Windows共通に環境変数からコンソールの文字コードとホームディレクトリを設定する |
|
14 | + |
|
15 | +use strict; |
|
16 | +use warnings; |
|
17 | +use utf8; |
|
18 | +use Encode; |
|
19 | + |
|
20 | +( $ENV{'LANG'} || '' ) =~ /\.(.*)$/; # ja_JP.UTF-8 |
|
21 | +my $charsetConsole = $1 || 'CP932'; |
|
22 | +my $charsetFile = 'UTF-8'; |
|
23 | + |
|
24 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
25 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
26 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
27 | + |
|
28 | +my $home = $ENV{'HOME'} || $ENV{'USERPROFILE'}; |
|
29 | +$home =~ s#\\#/#g; |
|
30 | + |
|
31 | +my $fileOut = $home . '/環境変数テスト.txt'; |
|
32 | + |
|
33 | +@ARGV = map{ decode( $charsetConsole, $_ ); } @ARGV; |
|
34 | + |
|
35 | +print "$home\n$fileOut\n"; |
|
36 | +print join( "\n", @ARGV ) . "\n"; |
|
37 | + |
|
38 | +open( my $fhout, ">:encoding($charsetFile)", encode( $charsetConsole, $fileOut ) ) |
|
39 | + or die( "$fileOut: " . decode( $charsetConsole, $! ) . "\n" ); |
|
40 | +print $fhout "テスト\n"; |
|
41 | +print $fhout join( "\n", @ARGV ) . "\n"; |
|
42 | +close( $fhout ); |
|
43 | + |
|
44 | +# EOF |
|
45 | +``` |
|
46 | + |
|
47 | +## リンク |
|
48 | +- [[Perl/環境変数]] |
|
49 | +- [[Perl/文字コード]] |
|
... | ... | \ No newline at end of file |
Perl/makeCodeHighlightKeyword.md
... | ... | @@ -0,0 +1,350 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- PukiWiki の [codehighlight](http://pukiwiki.sourceforge.jp/?%e8%87%aa%e4%bd%9c%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3%2f%63%6f%64%65%68%69%67%68%6c%69%67%68%74%2e%69%6e%63%2e%70%68%70) プラグイン用のキーワード設定ファイルを作成する。 |
|
5 | +- CSS のグループとキーワードを .yml ファイルから読み取る。 |
|
6 | +- 単語一つ一つにどのグループに属するか書くのが面倒なので…。 |
|
7 | +- 文字スイッチとコメントも設定ファイルから設定できるように機能追加。(2013/02/02) |
|
8 | +- アウトライン用文字スイッチも設定できるように機能追加。(2013-02-10) |
|
9 | +- Script-Fu用設定ファイルのサンプルを追加。(2013-02-10) |
|
10 | + |
|
11 | +# ソース |
|
12 | +- [makeKeyword.zip](makeKeyword.zip) |
|
13 | + |
|
14 | +## makeKeyword.pl |
|
15 | +```perl |
|
16 | +#!/usr/bin/perl |
|
17 | +# PukiWiki CodeHighlight プラグイン用キーワード設定ファイル生成スクリプト |
|
18 | + |
|
19 | +use strict; |
|
20 | +use warnings; |
|
21 | +use utf8; |
|
22 | +use Encode; |
|
23 | +use YAML::Syck; |
|
24 | + |
|
25 | +$YAML::Syck::ImplicitUnicode = 1; |
|
26 | +#$YAML::Syck::ImplicitTyping = 1; |
|
27 | +$YAML::Syck::Headless = 1; |
|
28 | + |
|
29 | +my $config_file = $ARGV[0] or die( "usage: makeKeyword <Config>\n" ); |
|
30 | +my $inputname = my $outputname = 'keyword.template.php'; |
|
31 | + |
|
32 | +my $config = YAML::Syck::LoadFile( "$config_file" ) or die( "$config_file: $!\n" ); |
|
33 | +$outputname =~ s/template/lc($config->{'Name'})/e; |
|
34 | +my $ignore_case = ( $config->{'IgnoreCase'} =~ /true|1/i ); |
|
35 | + |
|
36 | +my $charclass = ""; |
|
37 | +foreach my $class ( sort( keys( %{$config->{'CharClass'}} ) ) ){ |
|
38 | + foreach my $char ( @{$config->{'CharClass'}{$class}} ){ |
|
39 | + $charclass .= "\$switchHash['$char']\t= PLUGIN_CODE_$class;\n"; |
|
40 | + } |
|
41 | +} |
|
42 | + |
|
43 | +my $comment = ""; |
|
44 | +my @comment_switches = sort( keys( %{$config->{'Comment'}} ) ); |
|
45 | +foreach my $char ( @comment_switches ){ |
|
46 | + $comment .= "\$switchHash['$char']\t= PLUGIN_CODE_COMMENT;\n"; |
|
47 | +} |
|
48 | +$comment .= "\$code_comment = Array(\n"; |
|
49 | +foreach my $char ( @comment_switches ){ |
|
50 | + $comment .= "\t'$char' => Array(\n"; |
|
51 | + foreach my $def ( @{$config->{'Comment'}{$char}} ){ |
|
52 | + $comment .= "\t\tArray( '/^" . quotemeta( $def->[0] ). "/', \"$def->[1]\", $def->[2] ),\n"; |
|
53 | + } |
|
54 | + $comment .= "\t),\n"; |
|
55 | +} |
|
56 | +$comment .= ");\n"; |
|
57 | + |
|
58 | +my $outline = ""; |
|
59 | +foreach my $outline_pair ( @{$config->{'Outline'}} ){ |
|
60 | + $outline .= "\t\$switchHash['" . $outline_pair->[0] . "']\t= PLUGIN_CODE_BLOCK_START;\n"; |
|
61 | + $outline .= "\t\$switchHash['" . $outline_pair->[1] . "']\t= PLUGIN_CODE_BLOCK_END;\n"; |
|
62 | +} |
|
63 | + |
|
64 | +my $keywords = ""; |
|
65 | +my @types = sort( keys( %{$config->{'Keywords'}} ) ); |
|
66 | +for( my $i=0; $i<@types; ++$i ){ |
|
67 | + $keywords .= "// " . $types[$i] . "\n"; |
|
68 | + my $index = $i + 1; |
|
69 | + foreach my $word ( sort( @{$config->{'Keywords'}{$types[$i]}} ) ){ |
|
70 | + if ( $ignore_case ){ $word = lc( $word ); } |
|
71 | + $keywords .= "\t'$word'\t=> $index,\n"; |
|
72 | + } |
|
73 | +} |
|
74 | + |
|
75 | +open( my $IN, "<:utf8", $inputname ) |
|
76 | + or die( "$inputname: $!\n" ); |
|
77 | +my @body = <$IN>; |
|
78 | +close( $IN ); |
|
79 | +my $body = join( "", @body ); |
|
80 | + |
|
81 | +$body =~ s/__Name__/$config->{'Name'}/g; |
|
82 | +$body =~ s/__IgnoreCase__/($ignore_case)?'true':'false'/e; |
|
83 | +$body =~ s/__CharClass__\n/$charclass/; |
|
84 | +$body =~ s/__Comment__\n/$comment/; |
|
85 | +$body =~ s/__Outline__\n/$outline/; |
|
86 | +$body =~ s/__Types__\n/join("",map{"\t'$_',\n";}@types)/e; |
|
87 | +$body =~ s/__Keywords__\n/$keywords/; |
|
88 | + |
|
89 | +# CrLf で保存される |
|
90 | +open( my $OUT, ">:utf8", $outputname ) |
|
91 | + or die( "$outputname: $!\n" ); |
|
92 | +print $OUT $body; |
|
93 | +close( $OUT ); |
|
94 | + |
|
95 | +# EOF |
|
96 | +``` |
|
97 | + |
|
98 | +## keyword.template.php |
|
99 | +```php |
|
100 | +<?php |
|
101 | +/** |
|
102 | + * __Name__ キーワード定義ファイル |
|
103 | + */ |
|
104 | + |
|
105 | +$capital = __IgnoreCase__; |
|
106 | + |
|
107 | +__CharClass__ |
|
108 | + |
|
109 | +// コメント定義 |
|
110 | +__Comment__ |
|
111 | + |
|
112 | +// アウトライン用 |
|
113 | +if($mkoutline){ |
|
114 | +__Outline__ |
|
115 | +} |
|
116 | + |
|
117 | +$code_css = Array( |
|
118 | +__Types__ |
|
119 | +); |
|
120 | + |
|
121 | +$code_keyword = Array( |
|
122 | +__Keywords__ |
|
123 | +); |
|
124 | +?> |
|
125 | +``` |
|
126 | + |
|
127 | +# Dummy |
|
128 | +## ymlファイル |
|
129 | +```perl |
|
130 | +# Dummy キーワード |
|
131 | + |
|
132 | +Name: Dummy |
|
133 | +IgnoreCase: false |
|
134 | + |
|
135 | +CharClass: |
|
136 | + SPECIAL_IDENTIFIRE: [ "#", @ ] |
|
137 | + NONESCAPE_LITERAL: [ \' ] |
|
138 | + |
|
139 | +Comment: |
|
140 | + "/": [ |
|
141 | + [ /*, */, 2 ], |
|
142 | + [ //, \n, 1 ] |
|
143 | + ] |
|
144 | + "-": [ |
|
145 | + [ --, \n, 1 ] |
|
146 | + ] |
|
147 | + |
|
148 | +Outline: |
|
149 | + - [ "{", "}" ] |
|
150 | + |
|
151 | +Keywords: |
|
152 | + # オペレータ |
|
153 | + operator: [ |
|
154 | + Mod, Div, Not, Or, And |
|
155 | + ] |
|
156 | + |
|
157 | + # 識別子 |
|
158 | + identifier: [ |
|
159 | + New, In, This, Var, Const, With, Function |
|
160 | + ] |
|
161 | + |
|
162 | + # 制御構文 |
|
163 | + control: [ |
|
164 | + If, Else, While, For, Break, Continue, Switch, Case, Default, |
|
165 | + Return, Try, Catch |
|
166 | + ] |
|
167 | + |
|
168 | + # 標準関数 |
|
169 | + function: [ |
|
170 | + Abs, Floor, Ceil, Rand, Round |
|
171 | + ] |
|
172 | + |
|
173 | + # 定数 |
|
174 | + constant: [ |
|
175 | + "True", "False", "Null" |
|
176 | + ] |
|
177 | + |
|
178 | + # module, import, 将来対応する pragma |
|
179 | + pragma: [ |
|
180 | + module, import, using, |
|
181 | + '#define', '#undef', '#if', '#elif', '#else', '#endif', |
|
182 | + '#error', '#warning', '#region', '#endregion', '#line' |
|
183 | + ] |
|
184 | + |
|
185 | + # __stdcall などの処理系専用の奴とか |
|
186 | + system: [ |
|
187 | + Console, Dictionary, Encoding, Exception, IDictionary, Match, |
|
188 | + MatchCollection, Object, Program, Regex, String |
|
189 | + ] |
|
190 | + |
|
191 | + # 環境変数 |
|
192 | + environment: [ |
|
193 | + Env |
|
194 | + ] |
|
195 | + |
|
196 | + # SQL |
|
197 | + sql: [ |
|
198 | + SELECT, INTO, FROM, WHERE, IN, GROUP, HAVING, ORDER, BY, ASC, DESC, |
|
199 | + AS, DISTINCT, TOP, JOIN, "ON", LIMIT, UNION, ALL, |
|
200 | + INSERT, VALUES, DUPLICATE, KEY, UPDATE, SET, DELETE, |
|
201 | + USE, GO |
|
202 | + ] |
|
203 | + |
|
204 | +# EOF |
|
205 | +``` |
|
206 | + |
|
207 | +## 適用結果 |
|
208 | +```dummy |
|
209 | +/** |
|
210 | + Dummy サンプル |
|
211 | +*/ |
|
212 | +#if !defined(BUFFER) |
|
213 | +#define BUFFER (1024) |
|
214 | +#endif |
|
215 | + |
|
216 | +Var sql1 = qq{ |
|
217 | +-- ユーザ選択 |
|
218 | + SELECT `ID`, `Gender`, `Age` |
|
219 | + FROM `Users` |
|
220 | + WHERE `Name` == :Name |
|
221 | +}; |
|
222 | + |
|
223 | +Function isExistUser( username ){ |
|
224 | + Var find = False; |
|
225 | + Var id = ""; |
|
226 | + Var gender = 0; |
|
227 | + Var age = 0; |
|
228 | + Var sth = dbh.prepare( sql1 ); |
|
229 | + sth.bind( "Name", username ); |
|
230 | + sth.execute(); |
|
231 | + While( Var record = sth.fetchrow_array() ){ |
|
232 | + find = True; |
|
233 | + id = record[0]; |
|
234 | + gender = record[1]; |
|
235 | + age = record[2]; |
|
236 | + If ( gender == 2 And age > 30 ){ |
|
237 | + age = Ceil( age / 10 ) * 10; |
|
238 | + } |
|
239 | + Console.WriteLine("{0}: {1}, {2}", username, id, age); |
|
240 | + } |
|
241 | + Return ( find, id, age ); |
|
242 | +} |
|
243 | + |
|
244 | +// EOF |
|
245 | +``` |
|
246 | + |
|
247 | +# Script-Fu |
|
248 | +## ymlファイル |
|
249 | +```perl |
|
250 | +# Script-Fu キーワード |
|
251 | + |
|
252 | +Name: Script-Fu |
|
253 | +IgnoreCase: false |
|
254 | + |
|
255 | +CharClass: |
|
256 | + SPECIAL_IDENTIFIRE: [ "*", "!", "-" ] |
|
257 | + |
|
258 | +Comment: |
|
259 | + ";": [ |
|
260 | + [ ;, \n, 1 ] |
|
261 | + ] |
|
262 | + |
|
263 | +Outline: |
|
264 | + - [ "{", "}" ] |
|
265 | + - [ "(", ")" ] |
|
266 | + - [ "[", "]" ] |
|
267 | + |
|
268 | +Keywords: |
|
269 | + # オペレータ |
|
270 | + operator: [ |
|
271 | + ] |
|
272 | + |
|
273 | + # 識別子 |
|
274 | + identifier: [ |
|
275 | + define, let, let*, cons, list, vector, vector-, set, set!, for-each, lambda, |
|
276 | + if, char, |
|
277 | + car, cdr, caar, cadr, cdar, cddr, |
|
278 | + string-append, string-ref, |
|
279 | + gimp-context-pop, |
|
280 | + gimp-context-push, |
|
281 | + gimp-context-set-background, |
|
282 | + gimp-context-set-foreground, |
|
283 | + gimp-display-new, |
|
284 | + gimp-displays-flush, |
|
285 | + gimp-drawable-fill, |
|
286 | + gimp-drawable-get-name, |
|
287 | + gimp-drawable-height, |
|
288 | + gimp-drawable-width, |
|
289 | + gimp-edit-fill, |
|
290 | + gimp-file-save, |
|
291 | + gimp-image-add-layer, |
|
292 | + gimp-image-clean-all, |
|
293 | + gimp-image-flatten, |
|
294 | + gimp-image-get-layers, |
|
295 | + gimp-image-lower-layer, |
|
296 | + gimp-image-lower-layer-to-bottom, |
|
297 | + gimp-image-merge-down, |
|
298 | + gimp-image-new, |
|
299 | + gimp-image-resize, |
|
300 | + gimp-image-undo-group-end, |
|
301 | + gimp-image-undo-group-start, |
|
302 | + gimp-layer-copy, |
|
303 | + gimp-layer-new, |
|
304 | + gimp-layer-set-lock-alpha, |
|
305 | + gimp-layer-set-name, |
|
306 | + gimp-layer-set-offsets, |
|
307 | + gimp-layer-resize, |
|
308 | + gimp-selection-grow, |
|
309 | + gimp-selection-layer-alpha, |
|
310 | + gimp-selection-none, |
|
311 | + gimp-text-fontname, |
|
312 | + script-fu-menu-register, |
|
313 | + script-fu-register, |
|
314 | + script-fu-text-box, |
|
315 | + script-fu-util-image-add-layers |
|
316 | + ] |
|
317 | + |
|
318 | + # 制御構文 |
|
319 | + control: [ |
|
320 | + ] |
|
321 | + |
|
322 | + # 標準関数 |
|
323 | + function: [ |
|
324 | + ] |
|
325 | + |
|
326 | + # 定数 |
|
327 | + constant: [ |
|
328 | + "TRUE", "FALSE", |
|
329 | + PIXELS, RGB-IMAGE, NORMAL, |
|
330 | + BACKGROUND-FILL, FOREGROUND-FILL, |
|
331 | + SF-IMAGE, SF-DRAWABLE, SF-VALUE, SF-STRING, SF-COLOR, SF-TOGGLE, |
|
332 | + SF-ADJUSTMENT, SF-FONT, SF-BRUSH, SF-PATTERN, SF-GRADIENT, |
|
333 | + SF-PALETTE, SF-FILENAME, SF-DIRNAME, SF-OPTION, SF-ENUM, |
|
334 | + RUN-INTERACTIVE, RUN-NONINTERACTIVE, RUN-WITH-LAST-VALS |
|
335 | + ] |
|
336 | + |
|
337 | + # module, import, 将来対応する pragma |
|
338 | + pragma: [ |
|
339 | + ] |
|
340 | + |
|
341 | + # __stdcall などの処理系専用の奴とか |
|
342 | + system: [ |
|
343 | + ] |
|
344 | + |
|
345 | + # 環境変数 |
|
346 | + environment: [ |
|
347 | + ] |
|
348 | + |
|
349 | +# EOF |
|
350 | +``` |
|
... | ... | \ No newline at end of file |
Perl/nicoget.md
... | ... | @@ -0,0 +1,142 @@ |
1 | +# nicoget - ニコニコ動画のダウンロード |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- ニコニコ動画の flv/mp4/swf と、コメントのXMLをダウンロードします。 |
|
6 | + |
|
7 | +### 改変元 |
|
8 | +- [perl - 勝手に添削 - ニコニコ動画ダウンローダー](http://blog.livedoor.jp/dankogai/archives/50885358.html) |
|
9 | +- [perl - ニコニコ動画ダウンローダー新認証対応版](http://blog.livedoor.jp/dankogai/archives/50900305.html) |
|
10 | +- [perl - LWP::UserAgentで進捗表示しつつダウンロード](http://blog.livedoor.jp/dankogai/archives/51141631.html) |
|
11 | + |
|
12 | +### 変更点 |
|
13 | +- ファイルの種類に合わせて、拡張子を flv/mp4/swf に変える。 |
|
14 | +- 設定ファイルをスクリプトと同じ場所に置く。 |
|
15 | +- 保存先も設定ファイルに記述する。 |
|
16 | +- ログイン用のURL変更。 |
|
17 | +- エコノミーモードの判定を行う。 |
|
18 | +- ファイルをバイナリモードで保存。 |
|
19 | +- 進捗状況を表示する。 |
|
20 | +- オプションなしで起動したときにwarningが出るのに対処。(2009/04/12) |
|
21 | +- openのレイヤーをbytesからrawに変更。(2009/04/12) |
|
22 | + |
|
23 | +## ソース |
|
24 | +- [nicoget.zip](nicoget.zip) |
|
25 | + |
|
26 | +- nicoget.pl |
|
27 | +``` |
|
28 | +#!/usr/local/bin/perl |
|
29 | +# |
|
30 | +# nicoget.pl,v 0.1+0.2 2009/04/12 15:00:00 take-ash |
|
31 | +# |
|
32 | +# original: http://blog.livedoor.jp/dankogai/archives/50885358.html |
|
33 | +# original: http://blog.livedoor.jp/dankogai/archives/51141631.html |
|
34 | + |
|
35 | +use strict; |
|
36 | +use warnings; |
|
37 | +use utf8; |
|
38 | +use LWP::UserAgent; |
|
39 | +use HTTP::Cookies; |
|
40 | +use HTTP::Request; |
|
41 | +use HTTP::Headers; |
|
42 | +use CGI; |
|
43 | +use YAML::Syck; |
|
44 | + |
|
45 | +my %Ext = ( 'f'=>'flv', 'm'=>'mp4', 's'=>'swf', ); |
|
46 | + |
|
47 | +my $yaml = "./nicovideo.yml"; |
|
48 | +my $conf = YAML::Syck::LoadFile($yaml) or die "$yaml:$!"; |
|
49 | +my $savepath = $conf->{ 'savepath' }; |
|
50 | +delete $conf->{ 'savepath' }; |
|
51 | +if ( $savepath !~ /[\/|\\]$/ ){ |
|
52 | + $savepath .= '/'; |
|
53 | +} |
|
54 | + |
|
55 | +my $video_id = $ARGV[0] or die "usage: $0 [video_id|uri]\n"; |
|
56 | +$video_id =~ /((sm|nm|ca)?\d+)(\?.*)?$/; |
|
57 | +$video_id = $1; |
|
58 | + |
|
59 | +my $ua = LWP::UserAgent->new( keep_alive => 4 ); |
|
60 | +$ua->cookie_jar( {} ); |
|
61 | + |
|
62 | +warn "login as $conf->{mail}\n"; |
|
63 | +$ua->post( "https://secure.nicovideo.jp/secure/login?site=niconico" => $conf ); |
|
64 | + |
|
65 | +$ua->get("http://www.nicovideo.jp/watch/$video_id"); |
|
66 | +my $res = $ua->get("http://www.nicovideo.jp/api/getflv?v=$video_id"); |
|
67 | +my $q = CGI->new( $res->content ); |
|
68 | +my $uri = $q->param('url') or die "Failed: " . $res->content; |
|
69 | +$uri =~ /\/smile\?(.)\=[\d\.]+(\w+)?$/; |
|
70 | +my $ext = $Ext{ $1 } || 'flv'; |
|
71 | +my $low = ( defined( $2 ) ) ? $2 : "" ; |
|
72 | +my $filename = $savepath."$video_id$low.$ext"; |
|
73 | +my $req = HTTP::Request->new( |
|
74 | + GET => $uri |
|
75 | +); |
|
76 | +if ( $low ){ |
|
77 | + warn "economy mode\n"; |
|
78 | +} |
|
79 | +savewithprogress( $req, $filename ); |
|
80 | + |
|
81 | +$filename = $savepath."$video_id$low.xml"; |
|
82 | +my $header = HTTP::Headers->new; |
|
83 | +$header->header( Content_Type => 'text/xml' ); |
|
84 | +my $thread_id = $q->param('thread_id'); |
|
85 | +$req = HTTP::Request->new( |
|
86 | + POST => $q->param('ms'), |
|
87 | + $header, |
|
88 | + qq{<thread res_from="-500" version="20061206" thread="$thread_id" />} |
|
89 | +); |
|
90 | +savewithprogress( $req, $filename ); |
|
91 | + |
|
92 | +exit(); |
|
93 | + |
|
94 | +sub savewithprogress { |
|
95 | + my( $req, $filename ) = @_; |
|
96 | + my $uri = $req->uri; |
|
97 | + warn "$filename <= $uri\n"; |
|
98 | + open my $wfh, '>:raw', "$filename" or die "$filename:$!"; |
|
99 | + $res = $ua->request( |
|
100 | + $req, |
|
101 | + sub { |
|
102 | + my ( $chunk, $res, $proto ) = @_; |
|
103 | + print $wfh $chunk; |
|
104 | + my $size = tell $wfh; |
|
105 | + if (my $total = $res->header('Content-Length')){ |
|
106 | + printf STDERR ( "%d/%d (%.1f%%)\r", $size, $total, $size / $total * 100 ); |
|
107 | + } else { |
|
108 | + printf STDERR ( "%d/Unknown bytes\r", $size ); |
|
109 | + } |
|
110 | + } |
|
111 | + ); |
|
112 | + close $wfh; |
|
113 | + warn "\n", $res->status_line, "\n"; |
|
114 | +} |
|
115 | + |
|
116 | +# EOF |
|
117 | +``` |
|
118 | + |
|
119 | +- nicovideo.yml |
|
120 | +``` |
|
121 | +mail: your@host.name |
|
122 | +password: yourpassword |
|
123 | +savepath: C:/temp |
|
124 | +``` |
|
125 | + |
|
126 | +## リンク |
|
127 | +- [404 Blog Not Found](http://blog.livedoor.jp/dankogai/) |
|
128 | + - [perl - 勝手に添削 - ニコニコ動画ダウンローダー](http://blog.livedoor.jp/dankogai/archives/50885358.html) |
|
129 | + - [perl - ニコニコ動画ダウンローダー新認証対応版](http://blog.livedoor.jp/dankogai/archives/50900305.html) |
|
130 | + - [perl - LWP::UserAgentで進捗表示しつつダウンロード](http://blog.livedoor.jp/dankogai/archives/51141631.html) |
|
131 | + |
|
132 | +- [ニコニコ動画のFLVをダウンロードする userChrome.js スクリプト](http://blog.libelabo.jp/2007/04/05/nicovideo-download-userchrome-js/) |
|
133 | + |
|
134 | +- [ニコニコ動画をダウンロードできるようになるGreasemonkeyスクリプトのOpera版](http://muumoo.jp/news/2007/08/27/0nicovideodownloader.html) |
|
135 | + |
|
136 | +- [ニコニコ公式アニメポータルのrtmpeプロトコル動画をダウンロードする覚え書き](https://gist.github.com/tondol/7039259) |
|
137 | + |
|
138 | +- [プログラマーのための YAML 入門 (初級編)](http://jp.rubyist.net/magazine/?0009-YAML) |
|
139 | + |
|
140 | +- [CPAN:libwww-perl](http://search.cpan.org/dist/libwww-perl) |
|
141 | +- [CPAN:CGI](http://search.cpan.org/dist/CGI) |
|
142 | +- [CPAN:YAML](http://search.cpan.org/dist/YAML) |
|
... | ... | \ No newline at end of file |
Perl/packBit.md
... | ... | @@ -0,0 +1,132 @@ |
1 | +# pack関数でのビットフィールドの取り扱い |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- pack関数のテンプレートで'B'を指定した場合、どのように変換されるのかを確認する。 |
|
6 | +- pack する対象は、0/1が連なった文字列。 |
|
7 | +- 1文字が1ビットに対応する。 |
|
8 | +- 左詰で解釈され、不足分は 0 とみなされる。 |
|
9 | +- 指定桁より大きい部分は切り捨てられる。 |
|
10 | +- 0/1 以外の文字は ($x & 0x01) されて解釈される。(10進数として解釈されない)<br /> |
|
11 | +例) '256'→'010', '512'→'110', '513'→'111' |
|
12 | + |
|
13 | +## ソース |
|
14 | +- [packBit.zip](packBit.zip) |
|
15 | +```perl |
|
16 | +# pack('B',$x), pack('C',$x) のテスト |
|
17 | + |
|
18 | +use strict; |
|
19 | +use warnings; |
|
20 | +use utf8; |
|
21 | +use Encode; |
|
22 | +use YAML::Syck; |
|
23 | + |
|
24 | +$YAML::Syck::ImplicitUnicode = 1; |
|
25 | +$YAML::Syck::ImplicitTyping = 1; |
|
26 | +$YAML::Syck::SortKeys = 1; |
|
27 | + |
|
28 | +my $charsetConsole = 'CP932'; |
|
29 | +#my $charsetConsole = 'UTF-8'; |
|
30 | +my $charsetFile = 'UTF-8'; |
|
31 | + |
|
32 | +my @in = qw( |
|
33 | + 0 1 10 100 1000 10000 |
|
34 | + 01 001 0001 00001 |
|
35 | + 2 3 4 5 02 03 04 05 |
|
36 | + 256 512 513 |
|
37 | +); |
|
38 | +my @result = (); |
|
39 | +foreach my $in ( @in ){ |
|
40 | + my $pb = pack( 'B4', $in ); |
|
41 | + my $upb = unpack( 'B4', $pb ); |
|
42 | + my $pc = pack( 'C*', Int2Array( $in ) ); |
|
43 | + my $upc = [ unpack( 'C*', $pc ) ]; |
|
44 | + push( @result, { |
|
45 | + _in => $in, |
|
46 | + bit_pack => $pb, |
|
47 | + bit_unpack => $upb, |
|
48 | + char_pack => $pc, |
|
49 | + char_unpack => $upc, |
|
50 | + }); |
|
51 | +} |
|
52 | + |
|
53 | +print "Perl version: $]\n"; |
|
54 | +print join( "\t", qw( _in bit_pack bit_unpack char_pack char_unpack ) ) . "\n"; |
|
55 | + |
|
56 | +my $result = Dump( \@result ); |
|
57 | +{ |
|
58 | + no warnings 'uninitialized'; |
|
59 | + $result =~ s{ |
|
60 | + ^-\s*\n |
|
61 | + \s+[^:]+:\s+(.*)\n |
|
62 | + \s+[^:]+:\s+(.*)\n |
|
63 | + \s+[^:]+:\s+(.*)\n |
|
64 | + \s+[^:]+:\s+(.*)\n |
|
65 | + \s+[^:]+:\s*\n |
|
66 | + \s+-\s+([^\s]+)\n |
|
67 | + (?:\s+-\s+([^\s]+)\n)? |
|
68 | + }{ |
|
69 | + $1\t$2\t$3\t$4\t$5,$6\n |
|
70 | + }gmx; |
|
71 | +} |
|
72 | +$result =~ s/^\s+//gmx; |
|
73 | + |
|
74 | +print $result; |
|
75 | + |
|
76 | +exit; |
|
77 | + |
|
78 | +sub Int2Array |
|
79 | +{ |
|
80 | + my $arg = shift || 0; |
|
81 | + my @ret = (); |
|
82 | + if ( !!$arg ){ |
|
83 | + while( !!$arg ){ |
|
84 | + my $m = $arg & 0xff; |
|
85 | + unshift( @ret, $m ); |
|
86 | + $arg >>= 8; |
|
87 | + } |
|
88 | + } else { |
|
89 | + @ret = ( 0 ); |
|
90 | + } |
|
91 | + return @ret; |
|
92 | +} |
|
93 | + |
|
94 | +# EOF |
|
95 | +``` |
|
96 | + |
|
97 | +## 結果 |
|
98 | +``` |
|
99 | +Perl version: 5.014002 |
|
100 | +_in bit_pack bit_unpack char_pack char_unpack |
|
101 | +--- |
|
102 | +0 "\0" '0000' "\0" 0, |
|
103 | +1 "\x80" 1000 "\x01" 1, |
|
104 | +10 "\x80" 1000 "\n" 10, |
|
105 | +100 "\x80" 1000 d 100, |
|
106 | +1000 "\x80" 1000 "\x03\xE8" 3,232 |
|
107 | +10000 "\x80" 1000 "'\x10" 39,16 |
|
108 | +'01' "@" '0100' "\x01" 1, |
|
109 | +'001' " " '0010' "\x01" 1, |
|
110 | +'0001' "\x10" '0001' "\x01" 1, |
|
111 | +'00001' "\0" '0000' "\x01" 1, |
|
112 | +2 "\0" '0000' "\x02" 2, |
|
113 | +3 "\x80" 1000 "\x03" 3, |
|
114 | +4 "\0" '0000' "\x04" 4, |
|
115 | +5 "\x80" 1000 "\x05" 5, |
|
116 | +'02' "\0" '0000' "\x02" 2, |
|
117 | +'03' "@" '0100' "\x03" 3, |
|
118 | +'04' "\0" '0000' "\x04" 4, |
|
119 | +'05' "@" '0100' "\x05" 5, |
|
120 | +256 "@" '0100' "\x01\0" 1,0 |
|
121 | +512 "\xC0" 1100 "\x02\0" 2,0 |
|
122 | +513 "\xE0" 1110 "\x02\x01" 2,1 |
|
123 | +``` |
|
124 | + |
|
125 | +## リンク |
|
126 | +- Perl/MySQL-BIT |
|
127 | + |
|
128 | +- http://perldoc.jp/ |
|
129 | + - [perldoc.jp:func/pack](http://perldoc.jp/func/pack) |
|
130 | + - [perldoc.jp:func/vec](http://perldoc.jp/func/vec) |
|
131 | + |
|
132 | +- [Perl の数値変換](http://mikeneko.creator.club.ne.jp/~lab/perl/numerical_transform/) |
|
... | ... | \ No newline at end of file |
Perl/readXSV.md
... | ... | @@ -0,0 +1,102 @@ |
1 | +# CSV(TSV)の読み込み |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- CSV(TSV)を読み込んで、ヘッダ行をキーにしたハッシュの配列を作成する。 |
|
6 | +- ファイルの文字コードは UTF-8。 |
|
7 | +- { binary => 1 } がデフォルトで指定されるように変更。(2012/02/28) |
|
8 | +- 戻り値が配列のリファレンスであることを確認してからデリファレンスするようにした。(2012/02/28) |
|
9 | + |
|
10 | +## ソース |
|
11 | +- [readCSV.zip](readCSV.zip) |
|
12 | + |
|
13 | +### readCSV.pl |
|
14 | +```perl |
|
15 | +#!/usr/bin/perl |
|
16 | +# CSV(TSV)を読み込んで、ヘッダ行をキーにしたハッシュの配列を作成する。 |
|
17 | + |
|
18 | +use strict; |
|
19 | +use warnings; |
|
20 | +use utf8; |
|
21 | +use Encode; |
|
22 | +use Text::xSV::Slurp qw( xsv_slurp ); |
|
23 | +use YAML::Syck; |
|
24 | + |
|
25 | +$YAML::Syck::ImplicitUnicode = 1; |
|
26 | + |
|
27 | +my $charsetConsole = 'CP932'; |
|
28 | +#my $charsetConsole = 'UTF-8'; |
|
29 | +my $charsetFile = 'UTF-8'; |
|
30 | + |
|
31 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
32 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
33 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
34 | + |
|
35 | +my $filename = 'データ.txt'; |
|
36 | +my $csvoption = { sep_char => "\t" }; |
|
37 | + |
|
38 | +my @csv = readXSV( $filename, $csvoption ); |
|
39 | +print Dump( \@csv ) . "\n" ; |
|
40 | + |
|
41 | +sub readXSV |
|
42 | +{ |
|
43 | + my( $fname, $opt ) = @_; |
|
44 | + $opt = { binary => 1, %{$opt} }; |
|
45 | + open( my $fhin, "<:encoding($charsetFile)", encode( $charsetConsole, $fname ) ) |
|
46 | + or die( "$fname: $!" ); |
|
47 | + my @body = <$fhin>; |
|
48 | + close( $fhin ); |
|
49 | + my $ret = xsv_slurp( |
|
50 | + string => join( "", @body ), |
|
51 | + text_csv => $opt, |
|
52 | + ); |
|
53 | + return ( ref( $ret ) eq 'ARRAY' ) |
|
54 | + ? @{ $ret } |
|
55 | + : $ret ; |
|
56 | +} |
|
57 | + |
|
58 | +# EOF |
|
59 | +``` |
|
60 | + |
|
61 | +### 入力 |
|
62 | +| ID | Name | Gender | DOB | Comment | |
|
63 | +| --- | --- | --- | --- | --- | |
|
64 | +| 1 | 芳佳 | 2 | 1930/08/18 | 九字兼定 | |
|
65 | +| 2 | 美緒 | 2 | 1925/08/26 | ドーベルマン | |
|
66 | +| 3 | ミーナ | 2 | 1926/03/11 | 灰色狼 | |
|
67 | + |
|
68 | +### 出力 |
|
69 | +``` |
|
70 | +--- |
|
71 | +- |
|
72 | + Comment: 九字兼定 |
|
73 | + DOB: 1930/08/18 |
|
74 | + Gender: 2 |
|
75 | + ID: 1 |
|
76 | + Name: 芳佳 |
|
77 | +- |
|
78 | + Comment: ドーベルマン |
|
79 | + DOB: 1925/08/26 |
|
80 | + Gender: 2 |
|
81 | + ID: 2 |
|
82 | + Name: 美緒 |
|
83 | +- |
|
84 | + Comment: 灰色狼 |
|
85 | + DOB: 1926/03/11 |
|
86 | + Gender: 2 |
|
87 | + ID: 3 |
|
88 | + Name: ミーナ |
|
89 | +``` |
|
90 | + |
|
91 | +## リンク |
|
92 | +- [[Perl/NetWatcher]] |
|
93 | + |
|
94 | +- [CPAN:Text-xSV-Slurp](http://search.cpan.org/dist/Text-xSV-Slurp) |
|
95 | +- [CPAN:Text-CSV-Slurp](http://search.cpan.org/dist/Text-CSV-Slurp) |
|
96 | +- [CPAN:Text-CSV_XS](http://search.cpan.org/dist/Text-CSV_XS) |
|
97 | +- [CPAN:Text-CSV-Simple](http://search.cpan.org/dist/Text-CSV-Simple) |
|
98 | + |
|
99 | +- [404 Blog Not Found](http://blog.livedoor.jp/dankogai/) |
|
100 | + - [perl - CSVはText::CSV(_XS)?で](http://blog.livedoor.jp/dankogai/archives/50765677.html) |
|
101 | + - [TSV vs CSV](http://blog.livedoor.jp/dankogai/archives/50509945.html) |
|
102 | + - [perl - デフォルト値のperlらしい指定法](http://blog.livedoor.jp/dankogai/archives/51074877.html) |
|
... | ... | \ No newline at end of file |
Perl/updateEarth.md
... | ... | @@ -0,0 +1,93 @@ |
1 | +# updateEarth |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 機能 |
|
5 | +[Earth Dynamic DNS](http://mydns.to/)に登録した情報を更新するスクリプトです。 |
|
6 | + |
|
7 | +## ダウンロード |
|
8 | +- [updateEarth.zip](updateEarth.zip) |
|
9 | + |
|
10 | +## updateEarth.cgi |
|
11 | +``` |
|
12 | +#!/usr/local/bin/perl |
|
13 | + |
|
14 | +# Earth DynamicDNS の更新スクリプト |
|
15 | + |
|
16 | +$sUserName = 'username'; # ユーザ名 |
|
17 | +$sPassword = 'password'; # パスワード |
|
18 | +$sSubDomain = 'subdomain'; # サブドメイン |
|
19 | +$sDomain = 'mydns.to'; # ドメイン |
|
20 | +#$sDomain = 'ur.to'; |
|
21 | +$sMXHost = ''; # メールホスト |
|
22 | +$sMX = 'f'; # メールサーバ t:使う f:使わない |
|
23 | +$sWildcard = 't'; # ワイルドカード t:使う f:使わない |
|
24 | + |
|
25 | +# 成功した場合の結果 |
|
26 | +$sFileSuccess = 'updateEarth_success.log'; |
|
27 | + |
|
28 | +# IPアドレスを調べるサービスを行うアドレス |
|
29 | +$sIPCheckURI = 'http://www02.so-net.ne.jp/~shintan/gateway/ipcheck.cgi'; |
|
30 | + |
|
31 | +open( IN, $sFileSuccess ) || die( "can't open '".$sFileSuccess."'\n" ); |
|
32 | +@lines = <IN>; |
|
33 | +close( IN ); |
|
34 | +$sSuccessLog = join( "", @lines ); |
|
35 | + |
|
36 | +$sMyIP = &getURI( $sIPCheckURI ); |
|
37 | + |
|
38 | +if ( $sMyIP =~ /(\d+\.\d+\.\d+\.\d+)/ ){ |
|
39 | + $sMyIP = $1; |
|
40 | + $sEarthUpdateURI = 'http://' . $sUserName . ':' . $sPassword |
|
41 | + . '@mydns.to/member/domainedit.php?ip=' . $sMyIP |
|
42 | + . '&mxhost=' . $sMXHost . '&mx=' . $sMX . '&wc=' . $sWildcard |
|
43 | + . '&domain=' . $sDomain . '&subdomain=' . $sSubDomain . '&mode=e'; |
|
44 | + $sResult = &getURI( $sEarthUpdateURI ); |
|
45 | + if ( $sResult ne $sSuccessLog ){ |
|
46 | + print "Content-type: text/html; charset=Shift_JIS\n\n"; |
|
47 | + print $sResult."\n"; |
|
48 | + } else { |
|
49 | + # 成功したときは何もしない |
|
50 | + } |
|
51 | +} else { |
|
52 | + print "Content-type: text/plain; charset=Shift_JIS\n\n"; |
|
53 | + print "can't get my IP.\n"; |
|
54 | +} |
|
55 | + |
|
56 | +exit(); |
|
57 | + |
|
58 | +# --- Subroutine --- |
|
59 | +sub getURI { |
|
60 | + my( $URI ) = @_; |
|
61 | + |
|
62 | + use LWP::UserAgent; |
|
63 | + |
|
64 | + $ua = LWP::UserAgent->new; |
|
65 | + |
|
66 | + $req = HTTP::Request->new( GET => $URI); |
|
67 | + |
|
68 | + # send request |
|
69 | + $res = $ua->request( $req ); |
|
70 | + |
|
71 | + # check the outcome |
|
72 | + if ( $res->is_success ){ |
|
73 | + return $res->content; |
|
74 | + } else { |
|
75 | + return "Error: " . $res->status_line . "\n"; |
|
76 | + } |
|
77 | +} |
|
78 | + |
|
79 | +# EOF |
|
80 | +``` |
|
81 | + |
|
82 | +## ipcheck.cgi |
|
83 | +``` |
|
84 | +#!/usr/local/bin/perl |
|
85 | + |
|
86 | +print "Content-type: text/plain; charset=Shift_JIS\n\n"; |
|
87 | + |
|
88 | +$remote_addr = $ENV{"REMOTE_ADDR"}; |
|
89 | +printf( "%s", $remote_addr ); |
|
90 | + |
|
91 | +exit(); |
|
92 | + |
|
93 | +# EOF |
|
... | ... | \ No newline at end of file |
Perl/\343\202\252\343\203\226\343\202\270\343\202\247\343\202\257\343\203\210\346\214\207\345\220\221\343\203\227\343\203\255\343\202\260\343\203\251\343\203\237\343\203\263\343\202\260.md
... | ... | @@ -0,0 +1,448 @@ |
1 | +# オブジェクト指向プログラミング |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- 3x3のビットパターンを表現するクラスを作成し、これを使って回転しても重複しないパターンを探索する。 |
|
6 | +- ソース<br /> |
|
7 | +[BitPattern.zip](BitPattern.zip) |
|
8 | + |
|
9 | +## BitPattern.pm |
|
10 | +``` |
|
11 | +# BitPattern.pm |
|
12 | +# ビットパターンクラス |
|
13 | +# 数値に対応するNxNのマトリックスを表現するクラス |
|
14 | +# |
|
15 | +# N=3 (default) |
|
16 | +# | bit0 | bit1 | bit2 | |
|
17 | +# | bit3 | bit4 | bit5 | |
|
18 | +# | bit6 | bit7 | bit8 | |
|
19 | + |
|
20 | +package BitPattern; |
|
21 | + |
|
22 | +use strict; |
|
23 | +use warnings; |
|
24 | +use utf8; |
|
25 | + |
|
26 | +sub new { |
|
27 | + my $pkg = shift; |
|
28 | + bless { |
|
29 | + number => 0, |
|
30 | + unit => 3, |
|
31 | + pattern => [ [0,0,0], [0,0,0], [0,0,0], ], |
|
32 | + }, $pkg; |
|
33 | +} |
|
34 | + |
|
35 | +sub toString { |
|
36 | + my $self = shift; |
|
37 | + my $unit = $self->{unit}; |
|
38 | + my $pattern = "[ "; |
|
39 | + for( my $i=0; $i<$unit; $i++ ){ |
|
40 | + $pattern .= "[ "; |
|
41 | + for( my $j=0; $j<$unit; $j++ ){ |
|
42 | + $pattern .= ${$self->{pattern}}[ $i ][ $j ] . " "; |
|
43 | + } |
|
44 | + $pattern .= "] "; |
|
45 | + } |
|
46 | + $pattern .= "]"; |
|
47 | + |
|
48 | + return sprintf( "%04x / %s", $self->{number}, $pattern ); |
|
49 | +} |
|
50 | + |
|
51 | +sub clone { |
|
52 | + my $self = shift; |
|
53 | + my $unit = $self->{unit}; |
|
54 | + my $tmp = BitPattern->new(); |
|
55 | + # $tmp->{number} = $self->{number}; |
|
56 | + # $tmp->{unit} = $self->{unit}; |
|
57 | + # @{$tmp->{pattern}} = @{$self->{pattern}}; # rotateで失敗する? |
|
58 | + $tmp->set( $self->{number}, $self->{unit} ); |
|
59 | + return $tmp; |
|
60 | +} |
|
61 | + |
|
62 | +sub equals { |
|
63 | + my $self = shift; |
|
64 | + my $target = shift; |
|
65 | + return ( $self->{number} == $target->{number} ); |
|
66 | +} |
|
67 | + |
|
68 | +sub set { |
|
69 | + my $self = shift; |
|
70 | + my $num = $self->{number} = int( shift ); |
|
71 | + my $unit = $self->{unit} = int( shift || $self->{unit} || 3 ); # default=3 |
|
72 | + my @pattern = (); |
|
73 | + for( my $i=0; $i<$unit; $i++ ){ |
|
74 | + for( my $j=0; $j<$unit; $j++ ){ |
|
75 | + if ( $num & 1 ){ |
|
76 | + $pattern[ $i ][ $j ] = 1; |
|
77 | + } else { |
|
78 | + $pattern[ $i ][ $j ] = 0; |
|
79 | + } |
|
80 | + $num >>= 1; |
|
81 | + } |
|
82 | + } |
|
83 | + @{$self->{pattern}} = @pattern; |
|
84 | + return $self; |
|
85 | +} |
|
86 | + |
|
87 | +sub getNumber { |
|
88 | + my $self = shift; |
|
89 | + return $self->{number}; |
|
90 | +} |
|
91 | + |
|
92 | +sub getPatternArray { |
|
93 | + my $self = shift; |
|
94 | + return wantarray ? @{$self->{pattern}} : $self->{pattern}; |
|
95 | +} |
|
96 | + |
|
97 | +sub getPattern { |
|
98 | + my $self = shift; |
|
99 | + my $unit = $self->{unit}; |
|
100 | + my $pattern = ""; |
|
101 | + for( my $i=0; $i<$unit; $i++ ){ |
|
102 | + for( my $j=0; $j<$unit; $j++ ){ |
|
103 | + $pattern .= ${$self->{pattern}}[ $i ][ $j ] ? "*" : "-" ; |
|
104 | + } |
|
105 | + $pattern .= "\n"; |
|
106 | + } |
|
107 | + return $pattern; |
|
108 | +} |
|
109 | + |
|
110 | +# 時計回りに回転 |
|
111 | +sub rotate { |
|
112 | + my $self = shift; |
|
113 | + my $unit = $self->{unit}; |
|
114 | + my $tmp = $self->clone(); |
|
115 | + for( my $i=0; $i<$unit; $i++ ){ |
|
116 | + for( my $j=0; $j<$unit; $j++ ){ |
|
117 | + ${$self->{pattern}}[ $i ][ $j ] = |
|
118 | + ${$tmp->{pattern}}[ $unit - 1 - $j ][ $i ]; |
|
119 | + } |
|
120 | + } |
|
121 | + |
|
122 | + my $num = 0; |
|
123 | + for( my $i=$unit-1; $i>=0; $i-- ){ |
|
124 | + for( my $j=$unit-1; $j>=0; $j-- ){ |
|
125 | + $num <<= 1; |
|
126 | + $num += ${$self->{pattern}}[ $i ][ $j ]; |
|
127 | + } |
|
128 | + } |
|
129 | + $self->{number} = $num; |
|
130 | + |
|
131 | + return $self; |
|
132 | +} |
|
133 | + |
|
134 | +1; |
|
135 | + |
|
136 | +# EOF |
|
137 | +``` |
|
138 | + |
|
139 | +## testBitPattern.pl |
|
140 | +### ソース |
|
141 | +``` |
|
142 | +# testBitPattern.pl |
|
143 | +# ビットパターンクラスの動作テスト |
|
144 | + |
|
145 | +use strict; |
|
146 | +use warnings; |
|
147 | +use utf8; |
|
148 | +use Data::Dump qw(dump); |
|
149 | + |
|
150 | +use BitPattern; |
|
151 | + |
|
152 | +my $unit = 3; |
|
153 | + |
|
154 | +my $pattern = BitPattern->new(); |
|
155 | +my( @pat1, @pat2, $pattern2 ); |
|
156 | + |
|
157 | +$pattern->set( 0, $unit ); |
|
158 | + |
|
159 | +foreach ( 1, 2, 4, 8, 16, 32, 64, 128, 256, 170, 325 ){ |
|
160 | + $pattern->set( $_ ); |
|
161 | + @pat1 = split( "\n", $pattern->getPattern() ); |
|
162 | + $pattern2 = $pattern->clone(); |
|
163 | + $pattern2->rotate(); |
|
164 | + @pat2 = split( "\n", $pattern2->getPattern() ); |
|
165 | + printf( |
|
166 | + "%s\n%d\n%s\neq: %b\n", |
|
167 | + $pattern->toString(), $pattern->getNumber(), |
|
168 | + dump( $pattern->getPatternArray() ), $pattern->equals($pattern2) |
|
169 | + ); |
|
170 | + for( my $i=0; $i<$unit; $i++ ){ |
|
171 | + printf( "%s -> %s\n", $pat1[ $i ], $pat2[ $i ] ); |
|
172 | + } |
|
173 | + print "\n"; |
|
174 | +} |
|
175 | + |
|
176 | +# EOF |
|
177 | +``` |
|
178 | + |
|
179 | +### 実行結果 |
|
180 | +``` |
|
181 | +0001 / [ [ 1 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
182 | +1 |
|
183 | +([1, 0, 0], [0, 0, 0], [0, 0, 0]) |
|
184 | +eq: 0 |
|
185 | +*-- -> --* |
|
186 | +--- -> --- |
|
187 | +--- -> --- |
|
188 | + |
|
189 | +0002 / [ [ 0 1 0 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
190 | +2 |
|
191 | +([0, 1, 0], [0, 0, 0], [0, 0, 0]) |
|
192 | +eq: 0 |
|
193 | +-*- -> --- |
|
194 | +--- -> --* |
|
195 | +--- -> --- |
|
196 | + |
|
197 | +0004 / [ [ 0 0 1 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
198 | +4 |
|
199 | +([0, 0, 1], [0, 0, 0], [0, 0, 0]) |
|
200 | +eq: 0 |
|
201 | +--* -> --- |
|
202 | +--- -> --- |
|
203 | +--- -> --* |
|
204 | + |
|
205 | +0008 / [ [ 0 0 0 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
206 | +8 |
|
207 | +([0, 0, 0], [1, 0, 0], [0, 0, 0]) |
|
208 | +eq: 0 |
|
209 | +--- -> -*- |
|
210 | +*-- -> --- |
|
211 | +--- -> --- |
|
212 | + |
|
213 | +0010 / [ [ 0 0 0 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
214 | +16 |
|
215 | +([0, 0, 0], [0, 1, 0], [0, 0, 0]) |
|
216 | +eq: 1 |
|
217 | +--- -> --- |
|
218 | +-*- -> -*- |
|
219 | +--- -> --- |
|
220 | + |
|
221 | +0020 / [ [ 0 0 0 ] [ 0 0 1 ] [ 0 0 0 ] ] |
|
222 | +32 |
|
223 | +([0, 0, 0], [0, 0, 1], [0, 0, 0]) |
|
224 | +eq: 0 |
|
225 | +--- -> --- |
|
226 | +--* -> --- |
|
227 | +--- -> -*- |
|
228 | + |
|
229 | +0040 / [ [ 0 0 0 ] [ 0 0 0 ] [ 1 0 0 ] ] |
|
230 | +64 |
|
231 | +([0, 0, 0], [0, 0, 0], [1, 0, 0]) |
|
232 | +eq: 0 |
|
233 | +--- -> *-- |
|
234 | +--- -> --- |
|
235 | +*-- -> --- |
|
236 | + |
|
237 | +0080 / [ [ 0 0 0 ] [ 0 0 0 ] [ 0 1 0 ] ] |
|
238 | +128 |
|
239 | +([0, 0, 0], [0, 0, 0], [0, 1, 0]) |
|
240 | +eq: 0 |
|
241 | +--- -> --- |
|
242 | +--- -> *-- |
|
243 | +-*- -> --- |
|
244 | + |
|
245 | +0100 / [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 1 ] ] |
|
246 | +256 |
|
247 | +([0, 0, 0], [0, 0, 0], [0, 0, 1]) |
|
248 | +eq: 0 |
|
249 | +--- -> --- |
|
250 | +--- -> --- |
|
251 | +--* -> *-- |
|
252 | + |
|
253 | +00aa / [ [ 0 1 0 ] [ 1 0 1 ] [ 0 1 0 ] ] |
|
254 | +170 |
|
255 | +([0, 1, 0], [1, 0, 1], [0, 1, 0]) |
|
256 | +eq: 1 |
|
257 | +-*- -> -*- |
|
258 | +*-* -> *-* |
|
259 | +-*- -> -*- |
|
260 | + |
|
261 | +0145 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 0 1 ] ] |
|
262 | +325 |
|
263 | +([1, 0, 1], [0, 0, 0], [1, 0, 1]) |
|
264 | +eq: 1 |
|
265 | +*-* -> *-* |
|
266 | +--- -> --- |
|
267 | +*-* -> *-* |
|
268 | +``` |
|
269 | + |
|
270 | +## checkPattern.pl |
|
271 | +### ソース |
|
272 | +``` |
|
273 | +# checkPattern.pl |
|
274 | +# ビットパターンのチェック |
|
275 | +# 回転しても重複しないビットパターンを探索する |
|
276 | + |
|
277 | +use strict; |
|
278 | +use warnings; |
|
279 | +use utf8; |
|
280 | + |
|
281 | +use BitPattern; |
|
282 | + |
|
283 | +my $pattern = BitPattern->new(); |
|
284 | +my @check = (); |
|
285 | +my $count = 0; |
|
286 | + |
|
287 | +for( my $i=1; $i<512; $i++ ){ |
|
288 | + if ( !defined( $check[ $i ] ) ){ |
|
289 | + $count++; |
|
290 | + $pattern->set( $i ); |
|
291 | + printf( "%s\n", $pattern->toString() ); |
|
292 | + $check[ $pattern->rotate()->getNumber() ] = 0; |
|
293 | + $check[ $pattern->rotate()->getNumber() ] = 0; |
|
294 | + $check[ $pattern->rotate()->getNumber() ] = 0; |
|
295 | + $check[ $i ] = 1; |
|
296 | + } |
|
297 | +} |
|
298 | +printf( "count: %d\n", $count ); |
|
299 | + |
|
300 | +# EOF |
|
301 | +``` |
|
302 | + |
|
303 | +### 実行結果 |
|
304 | +``` |
|
305 | +0001 / [ [ 1 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
306 | +0002 / [ [ 0 1 0 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
307 | +0003 / [ [ 1 1 0 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
308 | +0005 / [ [ 1 0 1 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
309 | +0006 / [ [ 0 1 1 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
310 | +0007 / [ [ 1 1 1 ] [ 0 0 0 ] [ 0 0 0 ] ] |
|
311 | +000a / [ [ 0 1 0 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
312 | +000b / [ [ 1 1 0 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
313 | +000c / [ [ 0 0 1 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
314 | +000d / [ [ 1 0 1 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
315 | +000e / [ [ 0 1 1 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
316 | +000f / [ [ 1 1 1 ] [ 1 0 0 ] [ 0 0 0 ] ] |
|
317 | +0010 / [ [ 0 0 0 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
318 | +0011 / [ [ 1 0 0 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
319 | +0012 / [ [ 0 1 0 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
320 | +0013 / [ [ 1 1 0 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
321 | +0015 / [ [ 1 0 1 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
322 | +0016 / [ [ 0 1 1 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
323 | +0017 / [ [ 1 1 1 ] [ 0 1 0 ] [ 0 0 0 ] ] |
|
324 | +001a / [ [ 0 1 0 ] [ 1 1 0 ] [ 0 0 0 ] ] |
|
325 | +001b / [ [ 1 1 0 ] [ 1 1 0 ] [ 0 0 0 ] ] |
|
326 | +001c / [ [ 0 0 1 ] [ 1 1 0 ] [ 0 0 0 ] ] |
|
327 | +001d / [ [ 1 0 1 ] [ 1 1 0 ] [ 0 0 0 ] ] |
|
328 | +001e / [ [ 0 1 1 ] [ 1 1 0 ] [ 0 0 0 ] ] |
|
329 | +001f / [ [ 1 1 1 ] [ 1 1 0 ] [ 0 0 0 ] ] |
|
330 | +0021 / [ [ 1 0 0 ] [ 0 0 1 ] [ 0 0 0 ] ] |
|
331 | +0023 / [ [ 1 1 0 ] [ 0 0 1 ] [ 0 0 0 ] ] |
|
332 | +0025 / [ [ 1 0 1 ] [ 0 0 1 ] [ 0 0 0 ] ] |
|
333 | +0027 / [ [ 1 1 1 ] [ 0 0 1 ] [ 0 0 0 ] ] |
|
334 | +0028 / [ [ 0 0 0 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
335 | +0029 / [ [ 1 0 0 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
336 | +002a / [ [ 0 1 0 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
337 | +002b / [ [ 1 1 0 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
338 | +002c / [ [ 0 0 1 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
339 | +002d / [ [ 1 0 1 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
340 | +002e / [ [ 0 1 1 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
341 | +002f / [ [ 1 1 1 ] [ 1 0 1 ] [ 0 0 0 ] ] |
|
342 | +0031 / [ [ 1 0 0 ] [ 0 1 1 ] [ 0 0 0 ] ] |
|
343 | +0033 / [ [ 1 1 0 ] [ 0 1 1 ] [ 0 0 0 ] ] |
|
344 | +0035 / [ [ 1 0 1 ] [ 0 1 1 ] [ 0 0 0 ] ] |
|
345 | +0037 / [ [ 1 1 1 ] [ 0 1 1 ] [ 0 0 0 ] ] |
|
346 | +0038 / [ [ 0 0 0 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
347 | +0039 / [ [ 1 0 0 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
348 | +003a / [ [ 0 1 0 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
349 | +003b / [ [ 1 1 0 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
350 | +003c / [ [ 0 0 1 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
351 | +003d / [ [ 1 0 1 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
352 | +003e / [ [ 0 1 1 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
353 | +003f / [ [ 1 1 1 ] [ 1 1 1 ] [ 0 0 0 ] ] |
|
354 | +0044 / [ [ 0 0 1 ] [ 0 0 0 ] [ 1 0 0 ] ] |
|
355 | +0045 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 0 0 ] ] |
|
356 | +0046 / [ [ 0 1 1 ] [ 0 0 0 ] [ 1 0 0 ] ] |
|
357 | +0047 / [ [ 1 1 1 ] [ 0 0 0 ] [ 1 0 0 ] ] |
|
358 | +004c / [ [ 0 0 1 ] [ 1 0 0 ] [ 1 0 0 ] ] |
|
359 | +004d / [ [ 1 0 1 ] [ 1 0 0 ] [ 1 0 0 ] ] |
|
360 | +004e / [ [ 0 1 1 ] [ 1 0 0 ] [ 1 0 0 ] ] |
|
361 | +004f / [ [ 1 1 1 ] [ 1 0 0 ] [ 1 0 0 ] ] |
|
362 | +0054 / [ [ 0 0 1 ] [ 0 1 0 ] [ 1 0 0 ] ] |
|
363 | +0055 / [ [ 1 0 1 ] [ 0 1 0 ] [ 1 0 0 ] ] |
|
364 | +0056 / [ [ 0 1 1 ] [ 0 1 0 ] [ 1 0 0 ] ] |
|
365 | +0057 / [ [ 1 1 1 ] [ 0 1 0 ] [ 1 0 0 ] ] |
|
366 | +005c / [ [ 0 0 1 ] [ 1 1 0 ] [ 1 0 0 ] ] |
|
367 | +005d / [ [ 1 0 1 ] [ 1 1 0 ] [ 1 0 0 ] ] |
|
368 | +005e / [ [ 0 1 1 ] [ 1 1 0 ] [ 1 0 0 ] ] |
|
369 | +005f / [ [ 1 1 1 ] [ 1 1 0 ] [ 1 0 0 ] ] |
|
370 | +0061 / [ [ 1 0 0 ] [ 0 0 1 ] [ 1 0 0 ] ] |
|
371 | +0062 / [ [ 0 1 0 ] [ 0 0 1 ] [ 1 0 0 ] ] |
|
372 | +0063 / [ [ 1 1 0 ] [ 0 0 1 ] [ 1 0 0 ] ] |
|
373 | +0065 / [ [ 1 0 1 ] [ 0 0 1 ] [ 1 0 0 ] ] |
|
374 | +0066 / [ [ 0 1 1 ] [ 0 0 1 ] [ 1 0 0 ] ] |
|
375 | +0067 / [ [ 1 1 1 ] [ 0 0 1 ] [ 1 0 0 ] ] |
|
376 | +0069 / [ [ 1 0 0 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
377 | +006a / [ [ 0 1 0 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
378 | +006b / [ [ 1 1 0 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
379 | +006c / [ [ 0 0 1 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
380 | +006d / [ [ 1 0 1 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
381 | +006e / [ [ 0 1 1 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
382 | +006f / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 0 0 ] ] |
|
383 | +0071 / [ [ 1 0 0 ] [ 0 1 1 ] [ 1 0 0 ] ] |
|
384 | +0072 / [ [ 0 1 0 ] [ 0 1 1 ] [ 1 0 0 ] ] |
|
385 | +0073 / [ [ 1 1 0 ] [ 0 1 1 ] [ 1 0 0 ] ] |
|
386 | +0075 / [ [ 1 0 1 ] [ 0 1 1 ] [ 1 0 0 ] ] |
|
387 | +0076 / [ [ 0 1 1 ] [ 0 1 1 ] [ 1 0 0 ] ] |
|
388 | +0077 / [ [ 1 1 1 ] [ 0 1 1 ] [ 1 0 0 ] ] |
|
389 | +0079 / [ [ 1 0 0 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
390 | +007a / [ [ 0 1 0 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
391 | +007b / [ [ 1 1 0 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
392 | +007c / [ [ 0 0 1 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
393 | +007d / [ [ 1 0 1 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
394 | +007e / [ [ 0 1 1 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
395 | +007f / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 0 0 ] ] |
|
396 | +008d / [ [ 1 0 1 ] [ 1 0 0 ] [ 0 1 0 ] ] |
|
397 | +008e / [ [ 0 1 1 ] [ 1 0 0 ] [ 0 1 0 ] ] |
|
398 | +008f / [ [ 1 1 1 ] [ 1 0 0 ] [ 0 1 0 ] ] |
|
399 | +009d / [ [ 1 0 1 ] [ 1 1 0 ] [ 0 1 0 ] ] |
|
400 | +009e / [ [ 0 1 1 ] [ 1 1 0 ] [ 0 1 0 ] ] |
|
401 | +009f / [ [ 1 1 1 ] [ 1 1 0 ] [ 0 1 0 ] ] |
|
402 | +00aa / [ [ 0 1 0 ] [ 1 0 1 ] [ 0 1 0 ] ] |
|
403 | +00ab / [ [ 1 1 0 ] [ 1 0 1 ] [ 0 1 0 ] ] |
|
404 | +00ad / [ [ 1 0 1 ] [ 1 0 1 ] [ 0 1 0 ] ] |
|
405 | +00af / [ [ 1 1 1 ] [ 1 0 1 ] [ 0 1 0 ] ] |
|
406 | +00ba / [ [ 0 1 0 ] [ 1 1 1 ] [ 0 1 0 ] ] |
|
407 | +00bb / [ [ 1 1 0 ] [ 1 1 1 ] [ 0 1 0 ] ] |
|
408 | +00bd / [ [ 1 0 1 ] [ 1 1 1 ] [ 0 1 0 ] ] |
|
409 | +00bf / [ [ 1 1 1 ] [ 1 1 1 ] [ 0 1 0 ] ] |
|
410 | +00c5 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 1 0 ] ] |
|
411 | +00c6 / [ [ 0 1 1 ] [ 0 0 0 ] [ 1 1 0 ] ] |
|
412 | +00c7 / [ [ 1 1 1 ] [ 0 0 0 ] [ 1 1 0 ] ] |
|
413 | +00cd / [ [ 1 0 1 ] [ 1 0 0 ] [ 1 1 0 ] ] |
|
414 | +00ce / [ [ 0 1 1 ] [ 1 0 0 ] [ 1 1 0 ] ] |
|
415 | +00cf / [ [ 1 1 1 ] [ 1 0 0 ] [ 1 1 0 ] ] |
|
416 | +00d5 / [ [ 1 0 1 ] [ 0 1 0 ] [ 1 1 0 ] ] |
|
417 | +00d6 / [ [ 0 1 1 ] [ 0 1 0 ] [ 1 1 0 ] ] |
|
418 | +00d7 / [ [ 1 1 1 ] [ 0 1 0 ] [ 1 1 0 ] ] |
|
419 | +00dd / [ [ 1 0 1 ] [ 1 1 0 ] [ 1 1 0 ] ] |
|
420 | +00de / [ [ 0 1 1 ] [ 1 1 0 ] [ 1 1 0 ] ] |
|
421 | +00df / [ [ 1 1 1 ] [ 1 1 0 ] [ 1 1 0 ] ] |
|
422 | +00e5 / [ [ 1 0 1 ] [ 0 0 1 ] [ 1 1 0 ] ] |
|
423 | +00e7 / [ [ 1 1 1 ] [ 0 0 1 ] [ 1 1 0 ] ] |
|
424 | +00ed / [ [ 1 0 1 ] [ 1 0 1 ] [ 1 1 0 ] ] |
|
425 | +00ee / [ [ 0 1 1 ] [ 1 0 1 ] [ 1 1 0 ] ] |
|
426 | +00ef / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 1 0 ] ] |
|
427 | +00f5 / [ [ 1 0 1 ] [ 0 1 1 ] [ 1 1 0 ] ] |
|
428 | +00f7 / [ [ 1 1 1 ] [ 0 1 1 ] [ 1 1 0 ] ] |
|
429 | +00fd / [ [ 1 0 1 ] [ 1 1 1 ] [ 1 1 0 ] ] |
|
430 | +00fe / [ [ 0 1 1 ] [ 1 1 1 ] [ 1 1 0 ] ] |
|
431 | +00ff / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 1 0 ] ] |
|
432 | +0145 / [ [ 1 0 1 ] [ 0 0 0 ] [ 1 0 1 ] ] |
|
433 | +0147 / [ [ 1 1 1 ] [ 0 0 0 ] [ 1 0 1 ] ] |
|
434 | +014f / [ [ 1 1 1 ] [ 1 0 0 ] [ 1 0 1 ] ] |
|
435 | +0155 / [ [ 1 0 1 ] [ 0 1 0 ] [ 1 0 1 ] ] |
|
436 | +0157 / [ [ 1 1 1 ] [ 0 1 0 ] [ 1 0 1 ] ] |
|
437 | +015f / [ [ 1 1 1 ] [ 1 1 0 ] [ 1 0 1 ] ] |
|
438 | +016d / [ [ 1 0 1 ] [ 1 0 1 ] [ 1 0 1 ] ] |
|
439 | +016f / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 0 1 ] ] |
|
440 | +017d / [ [ 1 0 1 ] [ 1 1 1 ] [ 1 0 1 ] ] |
|
441 | +017f / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 0 1 ] ] |
|
442 | +01ef / [ [ 1 1 1 ] [ 1 0 1 ] [ 1 1 1 ] ] |
|
443 | +01ff / [ [ 1 1 1 ] [ 1 1 1 ] [ 1 1 1 ] ] |
|
444 | +count: 139 |
|
445 | +``` |
|
446 | + |
|
447 | +## リンク |
|
448 | +- [Perlオブジェクト指向プログラミング](http://www.rwds.net/kuroita/program/Perl_oo.html) |
|
... | ... | \ No newline at end of file |
Perl/\343\202\255\343\203\274\343\203\257\343\203\274\343\203\211\347\275\256\346\217\233.md
... | ... | @@ -0,0 +1,547 @@ |
1 | +[[_TOC_]] |
|
2 | +---- |
|
3 | +# 概要 |
|
4 | +- 置換キーワードリストに従って、入力ファイル中のキーワードを置換してファイルへ出力する。 |
|
5 | +- キーワード毎に何件置換したかをレポートする。 |
|
6 | +- 正規表現による置換も行える。(2007/06/08 更新) |
|
7 | +- SendTo から呼び出せるように変更。(2011/04/16) |
|
8 | +- オプションで、文字セットの指定、辞書の選択、エンターキー待ちするかどうかの選択、レポート出力するかどうかの選択をできるようにしました。(2011/05/08) |
|
9 | +- 置換時にマルチラインオプション(m)を使用するようにしました。(2011/05/08) |
|
10 | +- 複数行にわたる置換ルールを書けるようにしました。(2011/05/08) |
|
11 | +- 入力ファイルが指定されていないときはクリップボードに対して処理するようにしました。(2011/05/17) |
|
12 | +- 1つのルールの中でTabを複数回使えるようにしました。(2011/09/07) |
|
13 | +- 置換対象とするファイルに yml, yaml を加えました。(2011/09/07) |
|
14 | + |
|
15 | +# ダウンロード |
|
16 | +- [replaceKeyword.zip](replaceKeyword.zip) |
|
17 | + |
|
18 | +# ソースコード |
|
19 | +```perl |
|
20 | +# replaceKeyword.pl |
|
21 | +# by TakeAsh, 2011/09/07 |
|
22 | +# |
|
23 | +# 置換キーワードリストに従って、入力ファイル中のキーワードを置換してファイルへ出力する。 |
|
24 | +# 入力ファイルを指定しなかった場合は、クリップボードを対象に置換処理を行なう。 |
|
25 | +# 置換キーワードリストはこのスクリプトと同じディレクトリに保存しておくこと。 |
|
26 | +# |
|
27 | +# 置換キーワードリストは、下記の書式で必要な個数を列記する。 |
|
28 | +# {置換対象キーワード} \t+ {置換後の文字列} \n |
|
29 | +# 行頭に # がある行と空行は無視される。 |
|
30 | +# 置換後の文字列として「eval(~)」と記述しておくと、Perlの式として評価される。 |
|
31 | +# |
|
32 | +# このスクリプトはUTF-8Nで保存すること |
|
33 | + |
|
34 | +use strict; |
|
35 | +use warnings; |
|
36 | +use utf8; |
|
37 | +use Encode; |
|
38 | +use FindBin; |
|
39 | +#use FindBin::libs; |
|
40 | +use File::Basename; |
|
41 | +use Term::ReadKey; |
|
42 | +use Tkx; |
|
43 | +#use YAML::Syck; |
|
44 | + |
|
45 | +#$YAML::Syck::ImplicitUnicode = 1; |
|
46 | + |
|
47 | +my $charsetConsole = 'CP932'; |
|
48 | +my $charsetDefault = 'utf-8'; |
|
49 | +my $charsetFile = $charsetDefault; |
|
50 | + |
|
51 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
52 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
53 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
54 | + |
|
55 | +my $extDic = '.dic'; |
|
56 | +my $fileNameRepLst = 'replaceKeyword'; # 既定置換キーワードリストファイル名 |
|
57 | +my $fileNameReport = 'ReplaceReport.txt'; # レポート出力ファイル名 |
|
58 | +my $fileNameReportFull = ''; # レポート出力ファイルフルパス名(CP932) |
|
59 | +my $flgPause = 0; # 処理終了後エンターキー待ちするかどうか 0:しない 1:する |
|
60 | +my $flgReport = 0; # レポート出力するかどうか 0:しない 1:する |
|
61 | + |
|
62 | +my @extIn = map{ quotemeta( '.' . $_ ); } qw( txt htm html c cpp cs h pl pm js yml yaml ); |
|
63 | + |
|
64 | +my %Options = ( |
|
65 | + 'c' => { |
|
66 | + 'desc' => "<charset>\tファイルの文字セットを指定します。", |
|
67 | + 'sub' => sub{ |
|
68 | + $charsetFile = shift( @ARGV ); |
|
69 | + print STDERR ( "CharSet: $charsetFile\n" ); |
|
70 | + }, |
|
71 | + }, |
|
72 | + 'd' => { |
|
73 | + 'desc' => "<file>\tfile を辞書ファイルとして読み込みます。", |
|
74 | + 'sub' => sub{ loadDic( shift( @ARGV ) ); }, |
|
75 | + }, |
|
76 | + 'h' => { |
|
77 | + 'desc' => "\t\tヘルプを表示します。", |
|
78 | + 'sub' => \&help, |
|
79 | + }, |
|
80 | + 'p' => { |
|
81 | + 'desc' => "\t\t処理終了後エンターキーの入力を待ちます。", |
|
82 | + 'sub' => sub{ $flgPause = 1; }, |
|
83 | + }, |
|
84 | + 'v' => { |
|
85 | + 'desc' => "\t\t$fileNameReport に処理結果を出力します。", |
|
86 | + 'sub' => sub{ $flgReport = 1; }, |
|
87 | + }, |
|
88 | +); |
|
89 | + |
|
90 | +@ARGV = map{ decode( $charsetConsole, $_ ); } @ARGV; |
|
91 | + |
|
92 | +my @RepPairs =(); |
|
93 | +loadDic(); |
|
94 | + |
|
95 | +my @Files = (); |
|
96 | + |
|
97 | +# オプションはファイルより先に処理 |
|
98 | +while( my $arg = shift( @ARGV ) ){ |
|
99 | + if ( $arg =~ /^-(\w+)/ ){ |
|
100 | + my $optsub = $Options{$1}{'sub'}; |
|
101 | + if ( ref( $optsub ) eq 'CODE' ){ |
|
102 | + &{$optsub}; |
|
103 | + } else { |
|
104 | + die( "不正なオプション: $1\n" ); |
|
105 | + } |
|
106 | + } else { |
|
107 | + push( @Files, $arg ); |
|
108 | + } |
|
109 | +} |
|
110 | + |
|
111 | +my $REPO; |
|
112 | + |
|
113 | +# 自動フラッシュ有効化 |
|
114 | +$| = 1; |
|
115 | + |
|
116 | +if ( @Files <= 0 ){ |
|
117 | + # クリップボードに対して処理 |
|
118 | + $flgReport = 0; |
|
119 | + my $buffer = doReplace( Tkx::clipboard( 'get' ), \@RepPairs ); |
|
120 | + Tkx::clipboard( 'clear' ); |
|
121 | + Tkx::clipboard( 'append', $buffer ); |
|
122 | +} else { |
|
123 | + # ファイルに対して処理 |
|
124 | + my( $name, $path, $suffix ) = fileparse( $Files[0], @extIn ); |
|
125 | + if ( $flgReport ){ |
|
126 | + $fileNameReportFull = encode( $charsetConsole, $path . $fileNameReport ); |
|
127 | + open( $REPO, ">:utf8", $fileNameReportFull ) |
|
128 | + or die( "$path$fileNameReport: $!" ); |
|
129 | + } |
|
130 | + |
|
131 | + # ファイルの処理 |
|
132 | + while( my $fileNameIn = shift( @Files ) ){ |
|
133 | + print STDERR ( "$fileNameIn\n" ); |
|
134 | + my( $name, $path, $suffix ) = fileparse( $fileNameIn, @extIn ); |
|
135 | + if ( !$suffix ){ |
|
136 | + print STDERR ( "Skipped.\n" ); |
|
137 | + next; |
|
138 | + } |
|
139 | + |
|
140 | + # 出力ファイル名。既存のものは確認なしで上書きされる。 |
|
141 | + my $fileNameOut = $path . $name . '_replace' . $suffix; |
|
142 | + report( "InFile:\t%s\nOutFile:\t%s\n#\tN\tOld\tNew\n", $fileNameIn, $fileNameOut ); |
|
143 | + |
|
144 | + # 入力ファイル読み込み |
|
145 | + open( my $IN, "<:encoding($charsetFile)", encode( $charsetConsole, $fileNameIn ) ) |
|
146 | + or die( "$fileNameIn: $!\n" ); |
|
147 | + my $buffer = join( "", <$IN> ); |
|
148 | + close( $IN ); |
|
149 | + |
|
150 | + # 置換処理 |
|
151 | + $buffer = doReplace( $buffer, \@RepPairs ); |
|
152 | + |
|
153 | + # 置換結果出力 |
|
154 | + open( my $OUT, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) ) |
|
155 | + or die( "$fileNameOut: $!\n" ); |
|
156 | + print $OUT $buffer; |
|
157 | + close( $OUT ); |
|
158 | + } |
|
159 | + |
|
160 | + if ( $flgReport ){ |
|
161 | + close( $REPO ); |
|
162 | + } |
|
163 | +} |
|
164 | + |
|
165 | +# 自動フラッシュ無効化 |
|
166 | +$| = 0; |
|
167 | + |
|
168 | +if ( $flgPause ){ |
|
169 | + print STDERR ( "Hit Enter.\n" ); |
|
170 | + ReadKey(0); |
|
171 | +} |
|
172 | + |
|
173 | +exit(); |
|
174 | + |
|
175 | +# ヘルプの表示 |
|
176 | +sub help |
|
177 | +{ |
|
178 | + die( "使用法: replaceKeyword.pl [<オプション>] [<source> [<source2>...]]\n" . |
|
179 | + "$fileNameRepLst$extDic に従って文字列を置換します。\n" . |
|
180 | + "入力ファイルを省略した場合はクリップボードに対して処理が行なわれます。\n" . |
|
181 | + "オプション:\n" . |
|
182 | + join( "\n", map{ '-'.$_.' '.$Options{$_}{'desc'} } sort( keys( %Options ) ) ) . "\n" |
|
183 | + ); |
|
184 | +} |
|
185 | + |
|
186 | +# 置換キーワード取り込み |
|
187 | +sub loadDic |
|
188 | +{ |
|
189 | + my $fDic = ( shift || $fileNameRepLst ) . $extDic; |
|
190 | + open( my $REPLST, "<:utf8", encode( $charsetConsole, $FindBin::RealBin . '/' . $fDic ) ) |
|
191 | + or die( "$fDic: $!\n" ); |
|
192 | + @RepPairs =(); |
|
193 | + while( my $line = <$REPLST> ){ |
|
194 | + chomp( $line ); |
|
195 | + while( $line =~ /^(.*\S)\s+\\$/ ){ # 末尾が \ だったら次の行と結合 |
|
196 | + $line = $1; |
|
197 | + <$REPLST> =~ /^(.*)\s*$/; # 行末の空白を削除する |
|
198 | + $line .= $1; |
|
199 | + } |
|
200 | + if ( ( length( $line ) == 0 ) || ( $line =~ /^#/ ) ){ next }; |
|
201 | + $line =~ /^([^\t]+)(?:\t+)?([\s\S]*)$/; # Old, New を分割 (2回目以降のTabはそのまま残る) |
|
202 | + push( @RepPairs, [ $1, $2 || '' ] ); # New が undef の場合は空白にする |
|
203 | + } |
|
204 | + close( $REPLST ); |
|
205 | + if ( $fDic ne $fileNameRepLst . $extDic ){ |
|
206 | + print STDERR ( "Dictionary: $fDic\n" ); |
|
207 | + } |
|
208 | +} |
|
209 | + |
|
210 | +#レポート出力 |
|
211 | +sub report |
|
212 | +{ |
|
213 | + if ( $flgReport ){ |
|
214 | + printf $REPO ( @_ ); |
|
215 | + } |
|
216 | +} |
|
217 | + |
|
218 | +# 置換処理 |
|
219 | +sub doReplace |
|
220 | +{ |
|
221 | + my( $buf, $refPairs ) = @_; |
|
222 | + my $current = 0; |
|
223 | + foreach my $pair ( @{$refPairs} ){ |
|
224 | + my( $old, $new ) = @{ $pair }; |
|
225 | + my $n = 0; |
|
226 | + if ( $new =~ /^eval\((.*)\)$/ ){ |
|
227 | + no warnings 'uninitialized'; |
|
228 | + my $exp = $1; |
|
229 | + $n = ( $buf =~ s/$old/eval($exp)/egm ); |
|
230 | + } else { |
|
231 | + $n = ( $buf =~ s/$old/$new/gm ); |
|
232 | + } |
|
233 | + report( "%d\t%d\t%s\t%s\n", ++$current, $n, $old, $new ); |
|
234 | + printf STDERR ( "%d/%d\r", $current, scalar(@RepPairs) ); |
|
235 | + } |
|
236 | + report( "\n" ); |
|
237 | + print STDERR ( "\n" ); |
|
238 | + return $buf; |
|
239 | +} |
|
240 | + |
|
241 | +# EOF |
|
242 | +``` |
|
243 | + |
|
244 | +# 置換例 |
|
245 | + |
|
246 | +## 一括置換 |
|
247 | +### キーワードリスト |
|
248 | +``` |
|
249 | +# Old New |
|
250 | + |
|
251 | +# ラム |
|
252 | +です。 だ。 |
|
253 | +。 っちゃ。 |
|
254 | +私 ウチ |
|
255 | + |
|
256 | +# こども |
|
257 | +さ ちゃ |
|
258 | +し ち |
|
259 | +す ちゅ |
|
260 | +せ ちぇ |
|
261 | +そ ちょ |
|
262 | +サ チャ |
|
263 | +シ チ |
|
264 | +ス チュ |
|
265 | +セ チェ |
|
266 | +ソ チョ |
|
267 | +``` |
|
268 | + |
|
269 | +### 変換結果 |
|
270 | +| 入力 | 出力 | |
|
271 | +| --- | --- | |
|
272 | +| この度、私は、内閣総理大臣に任命されました。日本が、厳しい時期を乗り越え、新世紀の発展に向けた出発点に立った今、初の戦後生まれの総理として、国政を預かる重責を与えられたことに、身の引き締まる思いです。多くの国民の期待を正面から真摯に受け止め、身命を賭して、職務に取り組んでまいります。<br /> 国政を遂行するに当たり、私は、まず、自らの政治姿勢を、国民の皆様並びに議員各位に明らかにいたします。私は、特定の団体や個人のための政治を行うつもりは一切ありません。額に汗して勤勉に働き、家族を愛し、自分の暮らす地域や故郷を良くしたいと思い、日本の未来を信じたいと願っている人々、そしてすべての国民の期待に応える政治を行ってまいります。みんなが参加する、新しい時代を切り拓く政治、誰に対しても開かれ、誰もがチャレンジできる社会を目指し、全力投球することを約束いたします。<br /> 我が国は、経済、社会全般にわたる構造改革と、国民の自助努力の相乗効果により、長い停滞のトンネルを抜け出し、デフレからの脱却が視野に入るなど、改革の成果が現われ、未来への明るい展望が開けてきました。<br /> 一方、人口減少が現実のものになるとともに、都市と地方の間における不均衡や、勝ち組、負け組が固定化することへの懸念、厳しい財政事情など、我が国の今後の発展にとって解決すべき重要な課題が、我々の前に立ちはだかっています。家族の価値観、地域の温かさが失われたことによる痛ましい事件や、ルール意識を欠いた企業活動による不祥事が多発しています。さらに、北朝鮮のミサイル発射や、テロの頻発など、国際社会の平和と安全に対する新たな脅威も生じています。<br /> このような状況にあって、今後のあるべき日本の方向を、勇気をもって、国民に指し示すことこそ、一国のトップリーダーの果たすべき使命であると考えます。私が目指すこの国のかたちは、活力とチャンスと優しさに満ちあふれ、自律の精神を大事にする、世界に開かれた、「美しい国、日本」であります。この「美しい国」の姿を、私は次のように考えます。<br /> 1つ目は、文化、伝統、自然、歴史を大切にする国であります。<br /> 2つ目は、自由な社会を基本とし、規律を知る、凛とした国であります。<br /> 3つ目は、未来へ向かって成長するエネルギーを持ち続ける国であります。<br /> 4つ目は、世界に信頼され、尊敬され、愛される、リーダーシップのある国であります。<br /> この「美しい国」の実現のため、私は、自由民主党及び公明党による連立政権の安定した基盤に立って、「美しい国創り内閣」を組織しました。世界のグローバル化が進む中で、時代の変化に迅速かつ的確に対応した政策決定を行うため、官邸で総理を支えるスタッフについて、各省からの順送り人事を排し、民間からの人材も含め、総理自らが人選する枠組みを早急に構築するなど、官邸の機能を抜本的に強化し、政治のリーダーシップを確立します。未来は開かれているとの信念の下、たじろぐことなく、改革の炎を燃やし続けてまいります。 | この度、ウチは、内閣総理大臣に任命ちゃれまちたっちゃ。日本が、厳ちい時期を乗り越え、新世紀の発展に向けた出発点に立った今、初の戦後生まれの総理とちて、国政を預かる重責を与えられたことに、身の引き締まる思いだっちゃ。多くの国民の期待を正面から真摯に受け止め、身命を賭ちて、職務に取り組んでまいりまちゅっちゃ。<br /> 国政を遂行ちゅるに当たり、ウチは、まず、自らの政治姿勢を、国民の皆様並びに議員各位に明らかにいたちまちゅっちゃ。ウチは、特定の団体や個人のための政治を行うつもりは一切ありまちぇんっちゃ。額に汗ちて勤勉に働き、家族を愛ち、自分の暮らちゅ地域や故郷を良くちたいと思い、日本の未来を信じたいと願っている人々、ちょちてちゅべての国民の期待に応える政治を行ってまいりまちゅっちゃ。みんなが参加ちゅる、新ちい時代を切り拓く政治、誰に対ちても開かれ、誰もがチャレンジできる社会を目指ち、全力投球ちゅることを約束いたちまちゅっちゃ。<br /> 我が国は、経済、社会全般にわたる構造改革と、国民の自助努力の相乗効果により、長い停滞のトンネルを抜け出ち、デフレからの脱却が視野に入るなど、改革の成果が現われ、未来への明るい展望が開けてきまちたっちゃ。<br /> 一方、人口減少が現実のものになるとともに、都市と地方の間における不均衡や、勝ち組、負け組が固定化ちゅることへの懸念、厳ちい財政事情など、我が国の今後の発展にとって解決ちゅべき重要な課題が、我々の前に立ちはだかっていまちゅっちゃ。家族の価値観、地域の温かちゃが失われたことによる痛まちい事件や、ルール意識を欠いた企業活動による不祥事が多発ちていまちゅっちゃ。ちゃらに、北朝鮮のミチャイル発射や、テロの頻発など、国際社会の平和と安全に対ちゅる新たな脅威も生じていまちゅっちゃ。<br /> このような状況にあって、今後のあるべき日本の方向を、勇気をもって、国民に指ち示ちゅことこちょ、一国のトップリーダーの果たちゅべき使命であると考えまちゅっちゃ。ウチが目指ちゅこの国のかたちは、活力とチャンチュと優ちちゃに満ちあふれ、自律の精神を大事にちゅる、世界に開かれた、「美ちい国、日本」でありまちゅっちゃ。この「美ちい国」の姿を、ウチは次のように考えまちゅっちゃ。<br /> 1つ目は、文化、伝統、自然、歴史を大切にちゅる国でありまちゅっちゃ。<br /> 2つ目は、自由な社会を基本とち、規律を知る、凛とちた国でありまちゅっちゃ。<br /> 3つ目は、未来へ向かって成長ちゅるエネルギーを持ち続ける国でありまちゅっちゃ。<br /> 4つ目は、世界に信頼ちゃれ、尊敬ちゃれ、愛ちゃれる、リーダーチップのある国でありまちゅっちゃ。<br /> この「美ちい国」の実現のため、ウチは、自由民主党及び公明党による連立政権の安定ちた基盤に立って、「美ちい国創り内閣」を組織ちまちたっちゃ。世界のグローバル化が進む中で、時代の変化に迅速かつ的確に対応ちた政策決定を行うため、官邸で総理を支えるチュタッフについて、各省からの順送り人事を排ち、民間からの人材も含め、総理自らが人選ちゅる枠組みを早急に構築ちゅるなど、官邸の機能を抜本的に強化ち、政治のリーダーチップを確立ちまちゅっちゃ。未来は開かれているとの信念の下、たじろぐことなく、改革の炎を燃やち続けてまいりまちゅっちゃ。 | |
|
273 | + |
|
274 | +## 正規表現置換 |
|
275 | +### キーワードリスト |
|
276 | +``` |
|
277 | +\$Buf\[([^\]]+)\]({[^}]+}) eval('$Ref'.$2.'{\'A'.$1.'\'}') |
|
278 | +``` |
|
279 | + |
|
280 | +### 変換結果 |
|
281 | +| 入力 | 出力 | |
|
282 | +| --- | --- | |
|
283 | +| $result = sprintf( <br /> "%s : %d, %d, %d, %d\n" .<br /> "%s : %d, %d, %d, %d\n" .<br /> "%s : %d, %d, %d, %d\n", <br /> $Buf[0]{'x'}, $Buf[0]{'y'}, $Buf[0]{'dx'}, $Buf[0]{'dy'},<br /> $Buf[1]{'x'}, $Buf[1]{'y'}, $Buf[1]{'dx'}, $Buf[1]{'dy'},<br /> $Buf[2]{'x'}, $Buf[2]{'y'}, $Buf[2]{'dx'}, $Buf[2]{'dy'},<br /> );<br /> | $result = sprintf( <br /> "%s : %d, %d, %d, %d\n" .<br /> "%s : %d, %d, %d, %d\n" .<br /> "%s : %d, %d, %d, %d\n", <br /> $Ref{'x'}{'A0'}, $Ref{'y'}{'A0'}, $Ref{'dx'}{'A0'}, $Ref{'dy'}{'A0'},<br /> $Ref{'x'}{'A1'}, $Ref{'y'}{'A1'}, $Ref{'dx'}{'A1'}, $Ref{'dy'}{'A1'},<br /> $Ref{'x'}{'A2'}, $Ref{'y'}{'A2'}, $Ref{'dx'}{'A2'}, $Ref{'dy'}{'A2'},<br /> );<br /> | |
|
284 | + |
|
285 | +## HTML/XML をタグ単位で改行 |
|
286 | +### キーワードリスト |
|
287 | +``` |
|
288 | +# Old New |
|
289 | + |
|
290 | +# HTML/XML をタグ単位で改行 |
|
291 | +> eval(">\n") |
|
292 | +\n\s+ eval("\n") |
|
293 | +<([\w_-]+)([^>]*)>\n+([^<]*)<\/\1> eval("<$1$2>$3</$1>") |
|
294 | +#>(\s+)< eval("><") # 逆変換(改行を削除) |
|
295 | +``` |
|
296 | + |
|
297 | +## タブ区切りを PukiWiki のテーブルに変換 |
|
298 | +### キーワードリスト |
|
299 | +``` |
|
300 | +# タブ区切りを PukiWiki 用テーブルに変換 |
|
301 | + |
|
302 | +# メタ文字をエスケープ |
|
303 | +([|~>:]) eval(sprintf("&#x%02x;",ord($1))) |
|
304 | + |
|
305 | +# "" を削除 |
|
306 | +(?<=\t)?"([^\t\n]+)"(?=\s) eval($_=$1; s/""/"/g; $_;) |
|
307 | + |
|
308 | +# 単独の - は中央揃え |
|
309 | +(?<=\s)(-)(?=\s) eval("CENTER:$1") |
|
310 | + |
|
311 | +# 数値は右詰め |
|
312 | +(?<=\s)((?:[-+\d.e'"]|:)+)(?=\s) eval("RIGHT:$1") |
|
313 | + |
|
314 | +# OK,NG を中央揃えかつカラーに |
|
315 | +\b(OK|NG)\b eval("CENTER:COLOR(#".{ 'OK'=>'00FF00', 'NG'=>'FF0000' }->{$1}."):$1") |
|
316 | + |
|
317 | +# 末尾が「h/f」の行をヘッダ行/フッタ行と見なして各々の列に「~」を追加 (最大20列まで対応) |
|
318 | +^((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)? \ |
|
319 | +((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)? \ |
|
320 | +((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)? \ |
|
321 | +((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)? \ |
|
322 | +((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?((?:[^\t\n]*)\t)?(h|f)$ \ |
|
323 | + eval("~$1~$2~$3~$4~$5~$6~$7~$8~$9~$10~$11~$12~$13~$14~$15~$16~$17~$18~$19~$20$21") |
|
324 | +^(.*\t)~+(h|f)$ eval("$1$2") |
|
325 | + |
|
326 | +# ヘッダ行/フッタ行以外の第1列をヘッダに |
|
327 | +^([^:]+:)?([^~].*)$ eval("$1~$2") |
|
328 | + |
|
329 | +# colspan |
|
330 | +(~[^\t]+\t)((?:~\t)+) eval(@_=($1,$2); $_=$2; s/~/>/g; "$_$_[0]";) |
|
331 | + |
|
332 | +# rowspan |
|
333 | +(?<=\t)(?=\s) ~ |
|
334 | + |
|
335 | +\t | |
|
336 | +\A([\s\S]*)\Z eval("\n$1\n") |
|
337 | +\n eval("|\n|") |
|
338 | +\|(h|f)\|\n eval("|$1\n") |
|
339 | +^\|~?\|$ |
|
340 | +\A\|\n([\s\S]*[^\n]\n)\n*\|\Z eval("$1") |
|
341 | +``` |
|
342 | + |
|
343 | +### 変換結果 |
|
344 | +- 入力 |
|
345 | +``` |
|
346 | +"#" "文字コード" "改行コード" "Win" "Mac" h |
|
347 | + "結果" "サイズ/KB" "処理時間" "結果" "サイズ/KB" "処理時間" h |
|
348 | +1 "Shift_JIS" "CRLF" "OK" 8.00 "0:00'10""" "OK" 10.00 "0:00'08""" |
|
349 | +2 "CR" "NG" "-" "-" "OK" 10.00 "0:00'08""" |
|
350 | +3 "LF" "OK" 8.00 "0:00'10""" "NG" "-" "-" |
|
351 | +4 "UTF16" "CRLF" "OK" 12.00 "0:00'30""" "OK" 15.00 "0:00'30""" |
|
352 | +5 "CR" "NG" "-" "-" "OK" 15.00 "0:00'30""" |
|
353 | +6 "LF" "OK" 12.00 "0:00'30""" "NG" "-" "-" |
|
354 | +"#" "文字コード" "改行コード" "結果" "サイズ" "処理時間" "結果" "サイズ" "処理時間" f |
|
355 | +``` |
|
356 | + |
|
357 | +- 出力 |
|
358 | +| # | 文字コード | 改行コード | > | > | Win | > | > | Mac | |
|
359 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | |
|
360 | +| | | | 結果 | サイズ/KB | 処理時間 | 結果 | サイズ/KB | 処理時間 | |
|
361 | +| 1 | Shift_JIS | CRLF | OK | 8.00 | 0:00'10" | OK | 10.00 | 0:00'08" | |
|
362 | +| 2 | | CR | NG | - | - | OK | 10.00 | 0:00'08" | |
|
363 | +| 3 | | LF | OK | 8.00 | 0:00'10" | NG | - | - | |
|
364 | +| 4 | UTF16 | CRLF | OK | 12.00 | 0:00'30" | OK | 15.00 | 0:00'30" | |
|
365 | +| 5 | | CR | NG | - | - | OK | 15.00 | 0:00'30" | |
|
366 | +| 6 | | LF | OK | 12.00 | 0:00'30" | NG | - | - | |
|
367 | +| # | 文字コード | 改行コード | 結果 | サイズ | 処理時間 | 結果 | サイズ | 処理時間 | |
|
368 | + |
|
369 | +## Schema から XML に変換 |
|
370 | +### キーワードリスト |
|
371 | +``` |
|
372 | +# Schema から XML に変換 |
|
373 | + |
|
374 | +# フィールド |
|
375 | +\s+-\s+[^:]+:\s+[^\n]+\n \ |
|
376 | +\s+[^:]+:\s+[^\n]+\n \ |
|
377 | +\s+COLUMN_NAME:\s+([^\n]+)\n \ |
|
378 | +\s+DATA_TYPE:\s+([^\n]+)\n \ |
|
379 | +\s+[^:]+:\s+[^\n]+\n \ |
|
380 | +(?=\s*(-\s|\S|\Z)) \ |
|
381 | + eval( "\t<FIELD\tName=\"$1\"\tType=\"" . { \ |
|
382 | + 'int' => 'NUMBER', \ |
|
383 | + 'decimal' => 'NUMBER', \ |
|
384 | + 'money' => 'NUMBER', \ |
|
385 | + 'bit' => 'BOOL', \ |
|
386 | + 'date' => 'DATE', \ |
|
387 | + 'datetime' => 'DATE', \ |
|
388 | + 'time' => 'DATE', \ |
|
389 | + 'timestamp' => 'DATE', \ |
|
390 | + 'char' => 'TEXT', \ |
|
391 | + 'text' => 'TEXT', \ |
|
392 | + 'varchar' => 'TEXT', \ |
|
393 | + 'nchar' => 'TEXT', \ |
|
394 | + 'ntext' => 'TEXT', \ |
|
395 | + 'nvarchar' => 'TEXT', \ |
|
396 | + 'binary' => 'TEXT', \ |
|
397 | + 'image' => 'TEXT', \ |
|
398 | + 'varbinary' => 'TEXT', \ |
|
399 | + 'uniqueidentifier' => 'TEXT', \ |
|
400 | + }->{$2} . "\"\t/>\n" ) |
|
401 | + |
|
402 | +# テーブル名 |
|
403 | +^([^-\s][^:]+): \ |
|
404 | + eval("</TABLE>\n<TABLE\tName=\"$1\"\tPrimaryField=\"\">\n") |
|
405 | + |
|
406 | +# 後始末 |
|
407 | +\A---\s+</TABLE>\s+([\s\S]*)\Z \ |
|
408 | + eval("$1</TABLE>\n") |
|
409 | +``` |
|
410 | + |
|
411 | +### 変換結果 |
|
412 | +- 入力 |
|
413 | +``` |
|
414 | +--- |
|
415 | +クラスレベルTable: |
|
416 | + - |
|
417 | + CHARACTER_MAXIMUM_LENGTH: ~ |
|
418 | + COLUMN_DEFAULT: ~ |
|
419 | + COLUMN_NAME: ID |
|
420 | + DATA_TYPE: int |
|
421 | + IS_NULLABLE: 'NO' |
|
422 | + - |
|
423 | + CHARACTER_MAXIMUM_LENGTH: 30 |
|
424 | + COLUMN_DEFAULT: ~ |
|
425 | + COLUMN_NAME: クラスレベル |
|
426 | + DATA_TYPE: nvarchar |
|
427 | + IS_NULLABLE: 'NO' |
|
428 | +会員Table: |
|
429 | + - |
|
430 | + CHARACTER_MAXIMUM_LENGTH: ~ |
|
431 | + COLUMN_DEFAULT: ~ |
|
432 | + COLUMN_NAME: ID |
|
433 | + DATA_TYPE: int |
|
434 | + IS_NULLABLE: 'NO' |
|
435 | + - |
|
436 | + CHARACTER_MAXIMUM_LENGTH: 50 |
|
437 | + COLUMN_DEFAULT: ~ |
|
438 | + COLUMN_NAME: 姓 |
|
439 | + DATA_TYPE: nvarchar |
|
440 | + IS_NULLABLE: 'NO' |
|
441 | + - |
|
442 | + CHARACTER_MAXIMUM_LENGTH: 50 |
|
443 | + COLUMN_DEFAULT: ~ |
|
444 | + COLUMN_NAME: 名 |
|
445 | + DATA_TYPE: nvarchar |
|
446 | + IS_NULLABLE: 'NO' |
|
447 | + …(省略)… |
|
448 | +``` |
|
449 | +- 出力 |
|
450 | +``` |
|
451 | +<TABLE Name="クラスレベルTable" PrimaryField=""> |
|
452 | + <FIELD Name="ID" Type="NUMBER" /> |
|
453 | + <FIELD Name="クラスレベル" Type="TEXT" /> |
|
454 | +</TABLE> |
|
455 | +<TABLE Name="会員Table" PrimaryField=""> |
|
456 | + <FIELD Name="ID" Type="NUMBER" /> |
|
457 | + <FIELD Name="姓" Type="TEXT" /> |
|
458 | + <FIELD Name="名" Type="TEXT" /> |
|
459 | + <FIELD Name="誕生日" Type="DATE" /> |
|
460 | + <FIELD Name="性別" Type="NUMBER" /> |
|
461 | + <FIELD Name="Email" Type="TEXT" /> |
|
462 | + <FIELD Name="電話番号" Type="TEXT" /> |
|
463 | + <FIELD Name="郵便番号" Type="TEXT" /> |
|
464 | + <FIELD Name="住所1" Type="TEXT" /> |
|
465 | + <FIELD Name="住所2" Type="TEXT" /> |
|
466 | + <FIELD Name="クラスレベル" Type="NUMBER" /> |
|
467 | + <FIELD Name="前回ログイン" Type="DATE" /> |
|
468 | + <FIELD Name="備考" Type="TEXT" /> |
|
469 | +</TABLE> |
|
470 | +<TABLE Name="性別Table" PrimaryField=""> |
|
471 | + <FIELD Name="ID" Type="NUMBER" /> |
|
472 | + <FIELD Name="性別" Type="TEXT" /> |
|
473 | +</TABLE> |
|
474 | +``` |
|
475 | + |
|
476 | +## メール返信時の余分な行を削除 |
|
477 | +### キーワードリスト |
|
478 | +``` |
|
479 | +# Email返信時の余分な行を削除 (クリップボード用) |
|
480 | +# 「\r\r\n」があると余分な行になる? |
|
481 | + |
|
482 | +\n>\n(?=>) eval("\n") |
|
483 | +(>\n){2,} eval(">\n") |
|
484 | +\n\n(?!\n) eval("\n") |
|
485 | +\n{3,} eval("\n\n") |
|
486 | +>\x20(?=>) > |
|
487 | +\Z eval("\n\n") |
|
488 | +``` |
|
489 | + |
|
490 | +### 変換結果 |
|
491 | +- 入力 |
|
492 | +``` |
|
493 | +> |
|
494 | +> |
|
495 | +> |
|
496 | +> Dear John-san, |
|
497 | +> |
|
498 | +> I want to know ~~ |
|
499 | +> |
|
500 | +> Could you let us know ~~ |
|
501 | +> |
|
502 | +``` |
|
503 | +- 出力 |
|
504 | +``` |
|
505 | +> |
|
506 | +> Dear John-san, |
|
507 | +> I want to know ~~ |
|
508 | +> Could you let us know ~~ |
|
509 | +> |
|
510 | +``` |
|
511 | + |
|
512 | +## Email アドレスの引用符を統一 |
|
513 | +### キーワードリスト |
|
514 | +``` |
|
515 | +# Email アドレスの「"'~'"」を「"~"」に統一 |
|
516 | + |
|
517 | +"'([^']+)'" eval("\"$1\"") |
|
518 | +``` |
|
519 | + |
|
520 | +# 参考: Win32::Clipboard の場合 |
|
521 | +```perl |
|
522 | +use Win32::Clipboard; |
|
523 | + |
|
524 | +my $clip = Win32::Clipboard(); |
|
525 | +if ( $clip->IsText() ){ |
|
526 | + my $buffer = decode( 'UTF16LE', $clip->GetAs(CF_UNICODETEXT) || '' ); |
|
527 | + $buffer = doReplace( $buffer, \@RepPairs ); |
|
528 | + $clip->Set( encode( 'CP932', $buffer ) ); # UTF16LE で書き戻せない --; |
|
529 | +} |
|
530 | +``` |
|
531 | + |
|
532 | +# リンク |
|
533 | +- [[Perl/MSSQL_ImpExp]] |
|
534 | + |
|
535 | +- [スクリプティング言語資料室(仮)](http://www.kt.rim.or.jp/~kbk/) |
|
536 | + - [正規表現メモ](http://www.kt.rim.or.jp/~kbk/regex/regex.html) |
|
537 | + |
|
538 | +- [ハードなソフトの話](http://hardsoft.at.webry.info/) |
|
539 | + - [Windows版ActivePerlでUnicodeを正しくクリップボードにコピーする方法](http://hardsoft.at.webry.info/200904/article_9.html) |
|
540 | + |
|
541 | +- [CPAN:FindBin](http://search.cpan.org/dist/perl/lib/FindBin.pm) |
|
542 | +- [CPAN:FindBin::libs](http://search.cpan.org/dist/FindBin-libs/lib/FindBin/libs.pm) |
|
543 | +- [CPAN:File::Basename](http://search.cpan.org/dist/perl/lib/File/Basename.pm) |
|
544 | +- [CPAN:Term::ReadKey](http://search.cpan.org/dist/TermReadKey/ReadKey.pm) |
|
545 | +- [CPAN:Getopt-Long](http://search.cpan.org/dist/Getopt-Long) |
|
546 | +- [CPAN:Tkx](http://search.cpan.org/dist/Tkx) |
|
547 | +- [CPAN:Win32-Clipboard](http://search.cpan.org/dist/Win32-Clipboard) |
|
... | ... | \ No newline at end of file |
Perl/\343\203\207\343\202\243\343\203\254\343\202\257\343\203\210\343\203\252\343\201\256\345\206\215\345\270\260\345\207\246\347\220\206.md
... | ... | @@ -0,0 +1,153 @@ |
1 | +[[_TOC_]] |
|
2 | +- [[Perl/ファイルの一括処理]] |
|
3 | +- [[Perl/文字コード]] |
|
4 | + |
|
5 | +# 概要 |
|
6 | +- ディレクトリを再帰的に処理するサンプル。 |
|
7 | + |
|
8 | +# ソースコード |
|
9 | +## Win32::Unicode::Native 版 |
|
10 | +```perl |
|
11 | +# ファイル名のリストアップ, ファイル名の長さ付き |
|
12 | + |
|
13 | +use strict; |
|
14 | +use warnings; |
|
15 | +use utf8; |
|
16 | +use Encode; |
|
17 | +use Win32::Unicode::Native; |
|
18 | + |
|
19 | +my $charsetFile = 'UTF-8'; |
|
20 | + |
|
21 | +my $fileNameOut = "FileNames.txt"; |
|
22 | +my @targetDirs = map { 'D:/' . $_; } qw( |
|
23 | + aaa bbb ccc |
|
24 | +); |
|
25 | + |
|
26 | +my $prevDir = ''; |
|
27 | + |
|
28 | +open( my $OUT, '>', $fileNameOut ) or die( "$fileNameOut: $!\n" ); |
|
29 | +binmode( $OUT, ":encoding($charsetFile)" ); |
|
30 | +find( \&getName, @targetDirs ); |
|
31 | +close( $OUT ); |
|
32 | + |
|
33 | +sub getName |
|
34 | +{ |
|
35 | + my $args = shift; |
|
36 | + my $curFile = $args->{name}; |
|
37 | + my $curDir = $args->{dir}; |
|
38 | + if ( $prevDir ne $curDir ){ |
|
39 | + print( "$curDir\n" ); |
|
40 | + $prevDir = $curDir; |
|
41 | + } |
|
42 | + printf $OUT ( "%d\t%s\n", length( $curFile ), $curFile ); |
|
43 | +} |
|
44 | + |
|
45 | +# EOF |
|
46 | +``` |
|
47 | + |
|
48 | +## File::Next 版 |
|
49 | +```perl |
|
50 | +# ファイル名のリストアップ, ファイル名の長さ付き |
|
51 | + |
|
52 | +use strict; |
|
53 | +use warnings; |
|
54 | +use utf8; |
|
55 | +use Encode; |
|
56 | +use File::Next; |
|
57 | +use Path::Class; |
|
58 | +use Win32; |
|
59 | + |
|
60 | +#my $charsetConsole = 'UTF-8'; |
|
61 | +my $charsetConsole = 'CP932'; |
|
62 | +my $charsetFile = 'UTF-8'; |
|
63 | + |
|
64 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
65 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
66 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
67 | + |
|
68 | +my $fileNameOut = "FileNames.txt"; |
|
69 | + |
|
70 | +# 「RECYCLER」を拾わないように |
|
71 | +my @targetDirs = map{ encode( $charsetConsole, 'D:/' . $_ ); } qw( |
|
72 | + aaa bbb ccc |
|
73 | +); |
|
74 | + |
|
75 | +my $prevDir = ''; |
|
76 | +my $nextFiles = File::Next::files( @targetDirs ); |
|
77 | + |
|
78 | +open( my $OUT, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) ) |
|
79 | + or die( "$fileNameOut: $!\n" ); |
|
80 | +while( defined ( my $file = $nextFiles->() ) ){ |
|
81 | + # $file は CP932 エンコードかつ短いファイルネーム |
|
82 | + my $curFile = getUtf8PathName( $file ); |
|
83 | + my $curDir = getUtf8PathName( file( $file )->dir ); |
|
84 | + if ( $prevDir ne $curDir ){ |
|
85 | + print "$curDir\n"; |
|
86 | + $prevDir = $curDir; |
|
87 | + } |
|
88 | + printf $OUT ( "%d\t%s\n", length( $curFile ), $curFile ); |
|
89 | +} |
|
90 | +close( $OUT ); |
|
91 | + |
|
92 | +sub getUtf8PathName |
|
93 | +{ |
|
94 | + my $path = shift; |
|
95 | + $path = Win32::GetLongPathName( $path ); |
|
96 | + if ( ! Encode::is_utf8( $path ) ){ |
|
97 | + $path = decode( $charsetConsole, $path ); |
|
98 | + } |
|
99 | + return $path; |
|
100 | +} |
|
101 | + |
|
102 | +# EOF |
|
103 | +``` |
|
104 | + |
|
105 | +## 自前で再帰版 |
|
106 | +```perl |
|
107 | +#!/usr/local/bin/perl |
|
108 | + |
|
109 | +# カレントディレクトリ以下の全てのファイルを処理する。 |
|
110 | + |
|
111 | +recursive( '.' ); |
|
112 | + |
|
113 | +exit(); |
|
114 | + |
|
115 | +##### Subroutine |
|
116 | + |
|
117 | +# 再帰的にコピーする |
|
118 | +# @param[in] $sBaseDir 基準となるディレクトリ |
|
119 | +sub recursive |
|
120 | +{ |
|
121 | + my( $sBaseDir ) = @_; |
|
122 | + my( @FileLists, $sFileName ); |
|
123 | + |
|
124 | + @FileLists = glob( $sBaseDir.'/*' ); |
|
125 | + |
|
126 | + foreach $sFileName ( sort( @FileLists ) ){ |
|
127 | + if ( -d $sFileName ){ |
|
128 | + # ディレクトリだったら再帰呼び出し |
|
129 | + &recursive( $sFileName ); |
|
130 | + } elsif ( -f $sFileName ){ |
|
131 | + # ファイルだったら処理する |
|
132 | + print( $sFileName . "\n" ); |
|
133 | + } |
|
134 | + } |
|
135 | +} |
|
136 | + |
|
137 | +# EOF |
|
138 | +``` |
|
139 | + |
|
140 | +# リンク |
|
141 | +- [CPAN:Win32-Unicode](http://search.cpan.org/dist/Win32-Unicode) |
|
142 | + |
|
143 | +- [CPAN:perl/lib/File/Find.pm](http://search.cpan.org/dist/perl/lib/File/Find.pm) |
|
144 | +- [CPAN:File-Find-Rule](http://search.cpan.org/dist/File-Find-Rule) |
|
145 | + |
|
146 | +- [CPAN:File-Next](http://search.cpan.org/dist/File-Next) |
|
147 | + - Windows では、「RECYCLER」のようなシステム管理フォルダにアクセスして失敗することがある。 |
|
148 | + - ロングファイルネームではなく、8.3 形式の短いファイル名を返す。 |
|
149 | + |
|
150 | +- [CPAN:Win32](http://search.cpan.org/dist/Win32) |
|
151 | + - GetLongPathName() |
|
152 | + |
|
153 | +- [CPAN:Path-Class](http://search.cpan.org/dist/Path-Class) |
|
... | ... | \ No newline at end of file |
Perl/\343\203\225\343\202\241\343\202\244\343\203\253\343\201\256\344\270\200\346\213\254\345\207\246\347\220\206.md
... | ... | @@ -0,0 +1,96 @@ |
1 | +[[_TOC_]] |
|
2 | +- Perl/ディレクトリの再帰処理 |
|
3 | + |
|
4 | +# サイズがゼロのファイルを削除 |
|
5 | +## 概要 |
|
6 | +- カレントディレクトリからサイズがゼロのファイルを削除する。 |
|
7 | +- 「-d」オプションを付けると削除実行、無しだと削除対象のリストアップのみ行う。 |
|
8 | +- ドットファイルも対象とする。 |
|
9 | + |
|
10 | +## ソースコード |
|
11 | +- [delSizeZero.zip](delSizeZero.zip) |
|
12 | +```perl |
|
13 | +#!/usr/bin/perl |
|
14 | +# カレントディレクトリからサイズゼロのファイルを削除する |
|
15 | + |
|
16 | +use strict; |
|
17 | +use warnings; |
|
18 | +use utf8; |
|
19 | + |
|
20 | +my $progName = 'delSizeZero'; |
|
21 | +my $delete = 0; |
|
22 | + |
|
23 | +if ( @ARGV > 0 ){ |
|
24 | + if ( $ARGV[0] eq '-d' ){ |
|
25 | + $delete = 1; |
|
26 | + } else { |
|
27 | + die("List up files that are size 0.\nusage: $progName [-d]\n -d: delete them\n"); |
|
28 | + } |
|
29 | +} |
|
30 | + |
|
31 | +foreach my $file (sort(glob("{.*,*}"))){ |
|
32 | + if ( -f $file && -s $file == 0 ){ |
|
33 | + $file =~ m{([^;]+)$}; |
|
34 | + my $fileName = $1; |
|
35 | + print "$fileName\n"; |
|
36 | + if ( $delete ){ |
|
37 | + unlink($file) or die("$progName: $fileName: $!\n"); |
|
38 | + } |
|
39 | + } |
|
40 | +} |
|
41 | + |
|
42 | +# EOF |
|
43 | +``` |
|
44 | + |
|
45 | +## リンク |
|
46 | +- [CPAN:Path-Tiny](http://search.cpan.org/dist/Path-Tiny) |
|
47 | + |
|
48 | +- [File::Glob Ignores Dot Files](http://www.perlmonks.org/?node_id=309995) |
|
49 | + |
|
50 | +# テキストファイルからXML部分を抜き出し |
|
51 | +## 概要 |
|
52 | +- テキストファイルからXML部分を抜き出す。 |
|
53 | +- 1ファイルにXMLは1個。 |
|
54 | +- 文字コードはEUC。 |
|
55 | +- 処理はWindows上で行う。 |
|
56 | + |
|
57 | +## ソースコード |
|
58 | +```perl |
|
59 | +#!/usr/local/bin/perl |
|
60 | + |
|
61 | +# カレントディレクトリのテキストファイルのリスト |
|
62 | +@filelists = <./*.txt>; |
|
63 | +# print join( "\n", @filelists ); |
|
64 | + |
|
65 | +foreach $fname_in (@filelists){ |
|
66 | + $fname_out = $fname_in; |
|
67 | + $fname_out =~ s/\.txt/\.xml/; |
|
68 | + |
|
69 | + open( IN, $fname_in ); |
|
70 | + @lines = < IN >; |
|
71 | + close( IN ); |
|
72 | + $body = join( "", @lines ); |
|
73 | + |
|
74 | + # XML部分を正規表現で抜き出す |
|
75 | + # '.' は改行にマッチしないので、代わりに [\x00-\xff] を使う (マルチバイトストリングの場合) |
|
76 | + # unicode だと [\x0000-\xffff] を使う |
|
77 | + if ( $body =~ /^[\x00-\xff]*(\<\?xml [\x00-\xff]*\<\/[^\>]+\>)[\x00-\xff]*$/ ){ |
|
78 | + $body = $1 . "\n"; |
|
79 | + # CRLF から CR を削除 |
|
80 | + # $body =~ tr/\r//d; |
|
81 | + open( OUT, ">" . $fname_out ); |
|
82 | + # テキストモードだと自動的に CR が付加されるのでバイナリモードで書き出し |
|
83 | + binmode( OUT ); |
|
84 | + print OUT $body; |
|
85 | + close( OUT ); |
|
86 | + } |
|
87 | +} |
|
88 | + |
|
89 | +#EOF |
|
90 | +``` |
|
91 | + |
|
92 | +## リンク |
|
93 | +- [CPAN:Path-Class](http://search.cpan.org/dist/Path-Class) |
|
94 | + |
|
95 | +- [JPerl Advent Calendar 2010 Casual Trac](http://perl-users.jp/articles/advent-calendar/2010/casual/) |
|
96 | + - [Path::Classで簡単ファイル操作](http://perl-users.jp/articles/advent-calendar/2010/casual/15) |
|
... | ... | \ No newline at end of file |
Perl/\343\203\225\343\202\241\343\202\244\343\203\253\345\220\215\346\255\243\350\246\217\345\214\226.md
... | ... | @@ -0,0 +1,65 @@ |
1 | +# ファイル名の正規化 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- カレントディレクトリのファイル名をルールに従って正規化する。 |
|
6 | +- 正規化したいファイルを選択した後、SendTo から呼び出す。 |
|
7 | +``` |
|
8 | +perl.exe {fullpath}\normFileName.pl |
|
9 | +``` |
|
10 | +- 空白 -> _ |
|
11 | +- _v/r. -> _v/r ("v"または"r"に続く"."を削除。ただし拡張子の前の"."だったら削除しない) |
|
12 | +- エラー時にメッセージを表示するようにした。(2012/07/13) |
|
13 | + |
|
14 | +## ソース |
|
15 | +- [normFileName.zip](normFileName.zip) |
|
16 | +```perl |
|
17 | +# normFileName.pl |
|
18 | +# ファイル名を正規化する。 |
|
19 | +# 空白 -> _ |
|
20 | +# _v/r. -> _v/r ("v"または"r"に続く"."を削除。ただし拡張子の前の"."だったら削除しない) |
|
21 | + |
|
22 | +use strict; |
|
23 | +use warnings; |
|
24 | +use utf8; |
|
25 | +use Encode; |
|
26 | +use File::Basename; |
|
27 | +use Term::ReadKey; |
|
28 | + |
|
29 | +my $charset = 'CP932'; |
|
30 | + |
|
31 | +binmode( STDIN, ":encoding($charset)" ); |
|
32 | +binmode( STDOUT, ":encoding($charset)" ); |
|
33 | +binmode( STDERR, ":encoding($charset)" ); |
|
34 | + |
|
35 | +@ARGV = map{ decode( $charset, $_ ); } @ARGV; |
|
36 | + |
|
37 | +my @Ext = map{ ".$_" } qw( pdf zip mbs htm html txt doc docx xls xlsx mdb accdb ppt pptx ); |
|
38 | + |
|
39 | +foreach my $fileNameIn ( @ARGV ){ |
|
40 | + my( $name, $path, $suffix ) = fileparse( $fileNameIn, @Ext ); |
|
41 | + if ( $suffix ){ |
|
42 | + my $fn2 = $name; |
|
43 | + $fn2 =~ s/\s+/_/g; |
|
44 | + $fn2 =~ s/_+/_/g; |
|
45 | + $fn2 =~ s/(_[vr])\./$1/ig; |
|
46 | + $fn2 =~ s/(_[vr])[-\.](\d+)[-\.](\d+)/$1$2.$3/ig; |
|
47 | + if ( $name ne $fn2 ){ |
|
48 | + print( "old: ${name}${suffix}\nnew: ${fn2}${suffix}\n" ); |
|
49 | + rename( encode( $charset, $fileNameIn ), encode( $charset, $path . $fn2 . $suffix ) ) |
|
50 | + or print( "${name}${suffix}: $!\n" ); |
|
51 | + print( "\n" ); |
|
52 | + } |
|
53 | + } |
|
54 | +} |
|
55 | + |
|
56 | +warn( "Hit Enter.\n" ); |
|
57 | +ReadKey(0); |
|
58 | + |
|
59 | +# EOF |
|
60 | +``` |
|
61 | + |
|
62 | +## リンク |
|
63 | +- [[文字コード|Perl/文字コード]] |
|
64 | + |
|
65 | +- [CPAN:perl/lib/File/Basename.pm](http://search.cpan.org/dist/perl/lib/File/Basename.pm) |
|
... | ... | \ No newline at end of file |
Perl/\345\205\250\350\247\222\343\201\213\343\202\211\345\215\212\350\247\222\343\201\270\345\244\211\346\217\233.md
... | ... | @@ -0,0 +1,27 @@ |
1 | +# 全角から半角へ変換 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## ソースコード |
|
5 | +``` |
|
6 | +#!/usr/local/bin/perl |
|
7 | + |
|
8 | +# 全角英数記号を半角英数記号に置換 |
|
9 | +# このスクリプトは「UTF-8N」として保存すること |
|
10 | + |
|
11 | +use utf8; |
|
12 | +binmode( STDIN, ":encoding(utf8)" ); |
|
13 | +binmode( STDOUT, ":encoding(utf8)" ); |
|
14 | + |
|
15 | +while(<STDIN>){ |
|
16 | + tr/A-Za-z0-9!”#$%&’()/.\x{3000}/A-Za-z0-9!\"\#$%&'\(\)\/\.\x{0020}/; |
|
17 | + print STDOUT $_; |
|
18 | +} |
|
19 | + |
|
20 | +#EOF |
|
21 | +``` |
|
22 | + |
|
23 | +## リンク |
|
24 | +- [perl5.8のUnicodeサポート](http://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html) |
|
25 | + |
|
26 | +- [CPAN:Lingua-JA-Regular-Unicode](http://search.cpan.org/dist/Lingua-JA-Regular-Unicode) |
|
27 | +- [CPAN:Lingua-JA-Numbers](http://search.cpan.org/dist/Lingua-JA-Numbers) |
|
... | ... | \ No newline at end of file |
Perl/\345\217\202\347\205\247.md
... | ... | @@ -0,0 +1,64 @@ |
1 | +# 参照 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- ハッシュへの参照のテスト |
|
6 | + |
|
7 | +## ソース |
|
8 | +- [testRef.pl](testRef.pl) |
|
9 | +``` |
|
10 | +# ハッシュへの参照のテスト |
|
11 | + |
|
12 | +use strict; |
|
13 | +use warnings; |
|
14 | +use utf8; |
|
15 | +use Encode; |
|
16 | + |
|
17 | +binmode( STDIN, ':encoding(CP932)' ); |
|
18 | +binmode( STDOUT, ':encoding(CP932)' ); |
|
19 | +binmode( STDERR, ':encoding(CP932)' ); |
|
20 | + |
|
21 | +my $refHash = {}; |
|
22 | +p(); |
|
23 | + |
|
24 | +$refHash->{'distance'} = {}; |
|
25 | +p(); |
|
26 | + |
|
27 | +$refHash = func( $refHash ); |
|
28 | +p(); |
|
29 | + |
|
30 | +$refHash->{'distance'}{'value'} = 5; |
|
31 | +p(); |
|
32 | + |
|
33 | +$refHash = func( $refHash ); |
|
34 | +p(); |
|
35 | + |
|
36 | +sub p |
|
37 | +{ |
|
38 | + my $dist = $refHash->{'distance'} && $refHash->{'distance'}{'value'} || -1; |
|
39 | + printf( "%d\n", $dist ); |
|
40 | +} |
|
41 | + |
|
42 | +sub func |
|
43 | +{ |
|
44 | + my( $r ) = @_; |
|
45 | + if ( |
|
46 | + ref( $r ) eq 'HASH' |
|
47 | + && ref( $r->{'distance'} ) eq 'HASH' |
|
48 | + && $r->{'distance'}{'value'} |
|
49 | + ){ |
|
50 | + $r->{'distance'}{'value'} *= 2; |
|
51 | + } |
|
52 | + return $r; |
|
53 | +} |
|
54 | + |
|
55 | +# EOF |
|
56 | +``` |
|
57 | + |
|
58 | +## 出力結果 |
|
59 | +``` |
|
60 | +-1 |
|
61 | +-1 |
|
62 | +-1 |
|
63 | +5 |
|
64 | +10 |
|
... | ... | \ No newline at end of file |
Perl/\345\244\232\346\254\241\345\205\203\351\205\215\345\210\227.md
... | ... | @@ -0,0 +1,192 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +Perlでは配列の中に配列への参照を入れることができるので、これを使うと多次元配列が実現できる。 |
|
5 | + |
|
6 | +- [MultiDimensional.zip](MultiDimensional.zip) |
|
7 | + |
|
8 | +# 配列 |
|
9 | +- ソース |
|
10 | +```perl |
|
11 | +# 多次元配列 |
|
12 | + |
|
13 | +use strict; |
|
14 | +use warnings; |
|
15 | +use utf8; |
|
16 | + |
|
17 | +my @Array = (); |
|
18 | +$Array[0][0] = "a"; |
|
19 | +$Array[0][2] = "b"; |
|
20 | +$Array[1][1] = "c"; |
|
21 | +$Array[2][0] = "d"; |
|
22 | +$Array[2][3] = "e"; |
|
23 | + |
|
24 | +printAll1( \@Array ); |
|
25 | +printAll2( \@Array ); |
|
26 | + |
|
27 | +# @Array の内容を全置き換え。以前の内容は失われる |
|
28 | +@Array = ( |
|
29 | + [ undef, "a", undef, "b", ], |
|
30 | + [ "c", ], |
|
31 | + [ "d", undef, "e", ], |
|
32 | +); |
|
33 | + |
|
34 | +printAll1( \@Array ); |
|
35 | +printAll2( \@Array ); |
|
36 | + |
|
37 | +exit(); |
|
38 | + |
|
39 | +# 一定範囲を出力 |
|
40 | +sub printAll1 |
|
41 | +{ |
|
42 | + my( $refArray ) = @_; |
|
43 | + for( my $i=0; $i<3; ++$i ){ |
|
44 | + printf( "%d /", $i ); |
|
45 | + for( my $j=0; $j<4; ++$j ){ |
|
46 | + printf( "\t%d:'%s'", $j, ($refArray->[$i][$j] || '') ); |
|
47 | + } |
|
48 | + printf( "\n" ); |
|
49 | + } |
|
50 | + printf( "\n" ); |
|
51 | +} |
|
52 | + |
|
53 | +# 0から最大の添え字までを出力 |
|
54 | +sub printAll2 |
|
55 | +{ |
|
56 | + my( $refArray ) = @_; |
|
57 | + for( my $i=0; $i<scalar(@{$refArray}); ++$i ){ |
|
58 | + printf( "%d /", $i ); |
|
59 | + for( my $j=0; $j<scalar(@{$refArray->[$i]}); ++$j ){ |
|
60 | + printf( "\t%d:'%s'", $j, ($refArray->[$i][$j] || '') ); |
|
61 | + } |
|
62 | + printf( "\n" ); |
|
63 | + } |
|
64 | + printf( "\n" ); |
|
65 | +} |
|
66 | + |
|
67 | +# EOF |
|
68 | +``` |
|
69 | + |
|
70 | +- 出力結果 |
|
71 | +``` |
|
72 | +0 / 0:'a' 1:'' 2:'b' 3:'' |
|
73 | +1 / 0:'' 1:'c' 2:'' 3:'' |
|
74 | +2 / 0:'d' 1:'' 2:'' 3:'e' |
|
75 | + |
|
76 | +0 / 0:'a' 1:'' 2:'b' |
|
77 | +1 / 0:'' 1:'c' |
|
78 | +2 / 0:'d' 1:'' 2:'' 3:'e' |
|
79 | + |
|
80 | +0 / 0:'' 1:'a' 2:'' 3:'b' |
|
81 | +1 / 0:'c' 1:'' 2:'' 3:'' |
|
82 | +2 / 0:'d' 1:'' 2:'e' 3:'' |
|
83 | + |
|
84 | +0 / 0:'' 1:'a' 2:'' 3:'b' |
|
85 | +1 / 0:'c' |
|
86 | +2 / 0:'d' 1:'' 2:'e' |
|
87 | +``` |
|
88 | + |
|
89 | +# 連想配列 (ハッシュ) |
|
90 | +- ソース |
|
91 | +```perl |
|
92 | +# 多次元ハッシュ |
|
93 | + |
|
94 | +use strict; |
|
95 | +use warnings; |
|
96 | +use utf8; |
|
97 | + |
|
98 | +my %Hash = (); |
|
99 | +$Hash{'A'}{'a'} = "1"; |
|
100 | +$Hash{'A'}{'b'} = "2"; |
|
101 | +$Hash{'B'}{'a'} = "3"; |
|
102 | +$Hash{'B'}{'b'} = "4"; |
|
103 | +$Hash{'B'}{'c'} = "5"; |
|
104 | +$Hash{'C'}{'b'} = "6"; |
|
105 | +$Hash{'C'}{'c'} = "7"; |
|
106 | + |
|
107 | +printAll1( \%Hash ); |
|
108 | +printAll2( \%Hash ); |
|
109 | + |
|
110 | +# %Hash の内容を全置き換え。以前の内容は失われる |
|
111 | +%Hash = ( |
|
112 | + 'A' => { 'b'=>"11", }, |
|
113 | + 'B' => { 'a'=>"12", 'b'=>"13", 'c'=>"14", }, |
|
114 | +); |
|
115 | + |
|
116 | +printAll1( \%Hash ); |
|
117 | +printAll2( \%Hash ); |
|
118 | + |
|
119 | +# %{$Hash{'B'}} の内容を置き換え |
|
120 | +$Hash{'B'} = { 'b'=>"15", }; |
|
121 | +# %{$Hash{'C'}} の内容を追加 |
|
122 | +$Hash{'C'} = { 'a'=>"16", 'c'=>"17", }; |
|
123 | + |
|
124 | +printAll1( \%Hash ); |
|
125 | +printAll2( \%Hash ); |
|
126 | + |
|
127 | +exit(); |
|
128 | + |
|
129 | +# 一定範囲を出力 |
|
130 | +sub printAll1 |
|
131 | +{ |
|
132 | + my( $refHash ) = @_; |
|
133 | + my @Xs = qw( A B C ); |
|
134 | + my @Ys = qw( a b c ); |
|
135 | + |
|
136 | + foreach my $x ( @Xs ){ |
|
137 | + printf( "%s /", $x ); |
|
138 | + foreach my $y ( @Ys ){ |
|
139 | + printf( "\t%s:'%s'", $y, ($refHash->{$x}{$y} || '') ); |
|
140 | + } |
|
141 | + printf( "\n" ); |
|
142 | + } |
|
143 | + printf( "\n" ); |
|
144 | +} |
|
145 | + |
|
146 | +# 存在する要素を出力 |
|
147 | +sub printAll2 |
|
148 | +{ |
|
149 | + my( $refHash ) = @_; |
|
150 | + foreach my $x ( sort( keys( %{$refHash} ) ) ){ |
|
151 | + printf( "%s /", $x ); |
|
152 | + foreach my $y ( sort( keys( %{$refHash->{$x}} ) ) ){ |
|
153 | + printf( "\t%s:'%d'", $y, ($refHash->{$x}{$y} || '') ); |
|
154 | + } |
|
155 | + printf( "\n" ); |
|
156 | + } |
|
157 | + printf( "\n" ); |
|
158 | +} |
|
159 | + |
|
160 | +# EOF |
|
161 | +``` |
|
162 | + |
|
163 | +- 出力結果 |
|
164 | +``` |
|
165 | +A / a:'1' b:'2' c:'' |
|
166 | +B / a:'3' b:'4' c:'5' |
|
167 | +C / a:'' b:'6' c:'7' |
|
168 | + |
|
169 | +A / a:'1' b:'2' |
|
170 | +B / a:'3' b:'4' c:'5' |
|
171 | +C / b:'6' c:'7' |
|
172 | + |
|
173 | +A / a:'' b:'11' c:'' |
|
174 | +B / a:'12' b:'13' c:'14' |
|
175 | +C / a:'' b:'' c:'' |
|
176 | + |
|
177 | +A / b:'11' |
|
178 | +B / a:'12' b:'13' c:'14' |
|
179 | +C / |
|
180 | + |
|
181 | +A / a:'' b:'11' c:'' |
|
182 | +B / a:'' b:'15' c:'' |
|
183 | +C / a:'16' b:'' c:'17' |
|
184 | + |
|
185 | +A / b:'11' |
|
186 | +B / b:'15' |
|
187 | +C / a:'16' c:'17' |
|
188 | +``` |
|
189 | + |
|
190 | +# リンク |
|
191 | +- [サンプルコードによるPerl入門](http://d.hatena.ne.jp/perlcodesample/) |
|
192 | + - [Perlの配列とハッシュを自由に扱う](http://d.hatena.ne.jp/perlcodesample/20100930/1278596435) |
|
... | ... | \ No newline at end of file |
Perl/\346\226\207\345\255\227\343\202\263\343\203\274\343\203\211.md
... | ... | @@ -0,0 +1,456 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 文字列 -> 16進表記 |
|
4 | + |
|
5 | +## ソースコード |
|
6 | +```perl |
|
7 | +#!/usr/local/bin/perl |
|
8 | + |
|
9 | +# 文字列を16進表記に変換 |
|
10 | +# このスクリプトは、文字コード:UTF8N, 改行:LF として保存すること。 |
|
11 | + |
|
12 | +use utf8; |
|
13 | +use Encode qw/encode decode/; |
|
14 | +#binmode( STDOUT, ":encoding(utf8)" ); |
|
15 | + |
|
16 | +$message = 'ABCXYZあいうえおわゐゑをん'; |
|
17 | +$output = 'output.txt'; |
|
18 | + |
|
19 | +open( OUT, ">:encoding(utf8)", $output ) || die( "can't open '$output'.\n" ); |
|
20 | + |
|
21 | +printf OUT ( "str : %s\n", $message ); |
|
22 | +printf OUT ( "UCS2: %s\n", &str_to_ucs2( $message ) ); |
|
23 | +printf OUT ( "UTF8: %s\n", &str_to_utf8( $message ) ); |
|
24 | +printf OUT ( "UTF8: %s\n", &str_to_byte( $message, "utf8" ) ); |
|
25 | +printf OUT ( "SJIS: %s\n", &str_to_byte( $message, "shift_jis" ) ); |
|
26 | +printf OUT ( "euc : %s\n", &str_to_byte( $message, "euc-jp" ) ); |
|
27 | + |
|
28 | +close( OUT ); |
|
29 | + |
|
30 | +exit(); |
|
31 | + |
|
32 | +#### Subroutine #### |
|
33 | + |
|
34 | +# wide character 文字列として取り扱う |
|
35 | +sub str_to_ucs2 |
|
36 | +{ |
|
37 | + my( $sIn ) = @_; |
|
38 | + my( $sOut, $len, $i ); |
|
39 | + |
|
40 | + $sOut = ''; |
|
41 | + |
|
42 | + $len = length( $sIn ); |
|
43 | + for( $i=0; $i<$len; ++$i ){ |
|
44 | + $sOut .= sprintf( "%04x ", unpack( "U", substr( $sIn, $i, 1 ))); |
|
45 | + } |
|
46 | + chop( $sOut ); |
|
47 | + |
|
48 | + return $sOut; |
|
49 | +} |
|
50 | + |
|
51 | +# wide character 文字列 として取り扱う |
|
52 | +sub str_to_utf8 |
|
53 | +{ |
|
54 | + my( $sIn ) = @_; |
|
55 | + my( $sOut, $len, $i ); |
|
56 | + |
|
57 | + $sOut = ''; |
|
58 | + |
|
59 | + $len = length( $sIn ); |
|
60 | + for( $i=0; $i<$len; ++$i ){ |
|
61 | + $sOut .= unpack( "H8", substr( $sIn, $i, 1 ) ) . ' '; |
|
62 | + } |
|
63 | + chop( $sOut ); |
|
64 | + |
|
65 | + return $sOut; |
|
66 | +} |
|
67 | + |
|
68 | +# multi byte 文字列として取り扱う |
|
69 | +sub str_to_byte |
|
70 | +{ |
|
71 | + my( $sIn, $encoding ) = @_; |
|
72 | + my( $sOut, $len, $i ); |
|
73 | + |
|
74 | + $sOut = ''; |
|
75 | + |
|
76 | + $sIn = encode( $encoding, $sIn ); |
|
77 | + |
|
78 | + $len = length( $sIn ); |
|
79 | + for( $i=0; $i<$len; ++$i ){ |
|
80 | + $sOut .= unpack( "H2", substr( $sIn, $i, 1 ) ) . ' '; |
|
81 | + } |
|
82 | + chop( $sOut ); |
|
83 | + |
|
84 | + return $sOut; |
|
85 | +} |
|
86 | + |
|
87 | +# EOF |
|
88 | +``` |
|
89 | + |
|
90 | +## 出力結果 |
|
91 | +``` |
|
92 | +str : ABCXYZあいうえおわゐゑをん |
|
93 | +UCS2: 0041 0042 0043 0058 0059 005a 3042 3044 3046 3048 304a 308f 3090 3091 3092 3093 |
|
94 | +UTF8: 41 42 43 58 59 5a e38182 e38184 e38186 e38188 e3818a e3828f e38290 e38291 e38292 e38293 |
|
95 | +UTF8: 41 42 43 58 59 5a e3 81 82 e3 81 84 e3 81 86 e3 81 88 e3 81 8a e3 82 8f e3 82 90 e3 82 91 e3 82 92 e3 82 93 |
|
96 | +SJIS: 41 42 43 58 59 5a 82 a0 82 a2 82 a4 82 a6 82 a8 82 ed 82 ee 82 ef 82 f0 82 f1 |
|
97 | +euc : 41 42 43 58 59 5a a4 a2 a4 a4 a4 a6 a4 a8 a4 aa a4 ef a4 f0 a4 f1 a4 f2 a4 f3 |
|
98 | +``` |
|
99 | + |
|
100 | +# 16進表記 -> 文字列 |
|
101 | +- 「16進表記」「Base64エンコード」で7bitにされたUTF-8文字列を復元する。 |
|
102 | + |
|
103 | +## ソースコード |
|
104 | +```perl |
|
105 | +# UTF-8 <-> 16進 変換 |
|
106 | +# utf8-hex.pl |
|
107 | +# このスクリプトは、文字コード:UTF8N, 改行:LF として保存すること。 |
|
108 | + |
|
109 | +use strict; |
|
110 | +use warnings; |
|
111 | +use utf8; |
|
112 | +use Encode; |
|
113 | +use MIME::Base64; |
|
114 | + |
|
115 | +my $utf8str = "ABCあいうえお"; |
|
116 | +my $hexstr = "414243E38182E38184E38186E38188E3818A"; |
|
117 | +my $b64str = "QUJD44GC44GE44GG44GI44GK"; |
|
118 | + |
|
119 | +open( OUT, ">:utf8", "output.txt" ) || die( "can't open 'output.txt'.\n" ); |
|
120 | + |
|
121 | +printf OUT ( "utf8:\t'%s'\n", $utf8str ); |
|
122 | +printf OUT ( "->hex:\t'%s'\n", &Utf8ToHex( $utf8str ) ); |
|
123 | +printf OUT ( "hex:\t'%s'\n", $hexstr ); |
|
124 | +printf OUT ( "->utf8:\t'%s'\n", &HexToUtf8( $hexstr ) ); |
|
125 | +printf OUT ( "utf8:\t'%s'\n", $utf8str ); |
|
126 | +printf OUT ( "->B64:\t'%s'\n", &Utf8ToB64( $utf8str ) ); |
|
127 | +printf OUT ( "B64:\t'%s'\n", $b64str ); |
|
128 | +printf OUT ( "->utf8:\t'%s'\n", &B64ToUtf8( $b64str ) ); |
|
129 | + |
|
130 | +close( OUT ); |
|
131 | + |
|
132 | +exit(); |
|
133 | + |
|
134 | +sub Utf8ToHex |
|
135 | +{ |
|
136 | + my( $src ) = @_; |
|
137 | + return unpack( "H*", encode( "utf8", $src ) ); |
|
138 | +} |
|
139 | + |
|
140 | +sub HexToUtf8 |
|
141 | +{ |
|
142 | + my( $src ) = @_; |
|
143 | + return decode( "utf8", pack( "H*", $src ) ); |
|
144 | +} |
|
145 | + |
|
146 | +sub Utf8ToB64 |
|
147 | +{ |
|
148 | + my( $src ) = @_; |
|
149 | + return encode_base64( encode( "utf8", $src ), "" ); |
|
150 | +} |
|
151 | + |
|
152 | +sub B64ToUtf8 |
|
153 | +{ |
|
154 | + my( $src ) = @_; |
|
155 | + return decode( "utf8", decode_base64( $src ) ); |
|
156 | +} |
|
157 | + |
|
158 | +# EOF |
|
159 | +``` |
|
160 | + |
|
161 | +## 出力結果 |
|
162 | +``` |
|
163 | +utf8: 'ABCあいうえお' |
|
164 | +->hex: '414243e38182e38184e38186e38188e3818a' |
|
165 | +hex: '414243E38182E38184E38186E38188E3818A' |
|
166 | +->utf8: 'ABCあいうえお' |
|
167 | +utf8: 'ABCあいうえお' |
|
168 | +->B64: 'QUJD44GC44GE44GG44GI44GK' |
|
169 | +B64: 'QUJD44GC44GE44GG44GI44GK' |
|
170 | +->utf8: 'ABCあいうえお' |
|
171 | +``` |
|
172 | + |
|
173 | +# バイナリ <-> 16進変換 |
|
174 | +- [bin2hex.zip](bin2hex.zip) |
|
175 | +- バイナリファイルを16進表記のテキストファイルに変換します。 |
|
176 | +- アドレスとかチェックサムとか気の利いたものはつきません。 |
|
177 | +- .hexファイル中に[0-9a-fA-F][0-9a-fA-F]以外の文字があるとゴミデータになり、元のバイナリが再現されません。 |
|
178 | + |
|
179 | +## ソースコード bin2hex.pl |
|
180 | +```perl |
|
181 | +#!/usr/local/bin/perl |
|
182 | + |
|
183 | +# bin2hex.pl |
|
184 | +# バイナリファイルを16進に変換する。 |
|
185 | + |
|
186 | +use strict; |
|
187 | +use warnings; |
|
188 | +use utf8; |
|
189 | + |
|
190 | +my $ext = "hex"; |
|
191 | + |
|
192 | +my $fin = $ARGV[0] or die( "usage: $0 <binfile>\n" ); |
|
193 | + |
|
194 | +open( my $fhin, "<:raw", $fin ) or die( "$fin: $!\n" ); |
|
195 | +open( my $fhout, ">:utf8", "$fin.$ext" ) or die( "$fin.$ext: $!\n" ); |
|
196 | +while( <$fhin> ){ |
|
197 | + print $fhout unpack( "H*", $_ ); |
|
198 | +} |
|
199 | +close( $fhin ); |
|
200 | +close( $fhout ); |
|
201 | + |
|
202 | +# EOF |
|
203 | +``` |
|
204 | + |
|
205 | +## ソースコード hex2bin.pl |
|
206 | +```perl |
|
207 | +#!/usr/local/bin/perl |
|
208 | + |
|
209 | +# hex2bin.pl |
|
210 | +# 16進をバイナリファイルに変換する。 |
|
211 | + |
|
212 | +use strict; |
|
213 | +use warnings; |
|
214 | +use utf8; |
|
215 | + |
|
216 | +my $ext = "bin"; |
|
217 | + |
|
218 | +my $fin = $ARGV[0] or die( "usage: $0 <hexfile>\n" ); |
|
219 | + |
|
220 | +open( my $fhin, "<:utf8", $fin ) or die( "$fin: $!\n" ); |
|
221 | +open( my $fhout, ">:raw", "$fin.$ext" ) or die( "$fin.$ext: $!\n" ); |
|
222 | +while( <$fhin> ){ |
|
223 | + print $fhout pack( "H*", $_ ); |
|
224 | +} |
|
225 | +close( $fhin ); |
|
226 | +close( $fhout ); |
|
227 | + |
|
228 | +# EOF |
|
229 | +``` |
|
230 | + |
|
231 | +# ユニコード表現(&#xXXXX;)変換 |
|
232 | +## ダウンロード |
|
233 | +- [DecEncUni.zip](DecEncUni.zip) |
|
234 | + |
|
235 | +## decodeUni.pl |
|
236 | +```perl |
|
237 | +#!/usr/bin/perl |
|
238 | +# decodeUni.pl |
|
239 | +# ユニコード表現(&#xXXXX;)をUTF8文字に変換 |
|
240 | + |
|
241 | +use strict; |
|
242 | +use warnings; |
|
243 | +use utf8; |
|
244 | +use Encode; |
|
245 | + |
|
246 | +my $fileNameIn = 'Text1.txt'; |
|
247 | +my $fileNameOut = 'Text2.txt'; |
|
248 | + |
|
249 | +my $charsetConsole = 'CP932'; |
|
250 | +my $charsetFile = 'UTF-8'; |
|
251 | + |
|
252 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
253 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
254 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
255 | + |
|
256 | +open( my $fin, "<:encoding($charsetFile)", encode( $charsetConsole, $fileNameIn ) ) |
|
257 | + or die( "$fileNameIn: $!\n" ); |
|
258 | +my @body = <$fin>; |
|
259 | +close( $fin ); |
|
260 | + |
|
261 | +my $body = join( "", @body ); |
|
262 | +$body =~ s/&#x([0-9a-f]+);/chr( hex( $1 ) )/igmeo; |
|
263 | + |
|
264 | +open( my $fout, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) ) |
|
265 | + or die( "$fileNameOut: $!\n" ); |
|
266 | +print $fout $body; |
|
267 | +close( $fout ); |
|
268 | + |
|
269 | +# EOF |
|
270 | +``` |
|
271 | + |
|
272 | +## encodeUni.pl |
|
273 | +```perl |
|
274 | +#!/usr/bin/perl |
|
275 | +# encodeUni.pl |
|
276 | +# UTF8文字の内、ShiftJIS外の文字をユニコード表現(&#xXXXX;)に変換 |
|
277 | + |
|
278 | +use strict; |
|
279 | +use warnings; |
|
280 | +use utf8; |
|
281 | +use Encode; |
|
282 | + |
|
283 | +my $fileNameIn = 'Text2.txt'; |
|
284 | +my $fileNameOut = 'Text3.txt'; |
|
285 | + |
|
286 | +my $charsetConsole = 'CP932'; |
|
287 | +my $charsetFile = 'UTF-8'; |
|
288 | + |
|
289 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
290 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
291 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
292 | + |
|
293 | +open( my $fin, "<:encoding($charsetFile)", encode( $charsetConsole, $fileNameIn ) ) |
|
294 | + or die( "$fileNameIn: $!\n" ); |
|
295 | +my @body = <$fin>; |
|
296 | +close( $fin ); |
|
297 | + |
|
298 | +my $body = join( "", @body ); |
|
299 | +$body =~ s/([^\x00-\xff])/encodeUnlessSJIS( $1 )/igmeo; |
|
300 | +$body =~ s/([^[:print:]])/sprintf( "&#x%X;", ord( $1 ) )/gmeo; |
|
301 | + |
|
302 | +open( my $fout, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) ) |
|
303 | + or die( "$fileNameOut: $!\n" ); |
|
304 | +print $fout $body; |
|
305 | +close( $fout ); |
|
306 | + |
|
307 | +sub issjis |
|
308 | +{ |
|
309 | + my( $utf8 ) = @_; |
|
310 | + return ( $utf8 eq '?' || encode( 'CP932', $utf8 ) ne '?' ); |
|
311 | +} |
|
312 | + |
|
313 | +sub encodeUnlessSJIS |
|
314 | +{ |
|
315 | + my( $utf8 ) = @_; |
|
316 | + return ( issjis( $utf8 ) ) ? $utf8 : sprintf( "&#x%X;", ord( $utf8 ) ) ; |
|
317 | +} |
|
318 | + |
|
319 | +# EOF |
|
320 | +``` |
|
321 | + |
|
322 | +## サンプルデータ Text1.txt |
|
323 | +``` |
|
324 | +漢字のファイル |
|
325 | +ちゃんと変換されていますか? |
|
326 | +Is this file converted correctly? |
|
327 | +高髙 |
|
328 | +崎﨑 |
|
329 | +吉𠮷 |
|
330 | +叱𠮟 |
|
331 | +剥剝 |
|
332 | +填塡 |
|
333 | +頬頰 |
|
334 | +	タブ制御コード |
|
335 | +``` |
|
336 | + |
|
337 | +## 出力結果 Text2.txt |
|
338 | +![Text2.png](Text2.png) |
|
339 | + |
|
340 | +## 出力結果 Text3.txt |
|
341 | +``` |
|
342 | +漢字のファイル |
|
343 | +ちゃんと変換されていますか? |
|
344 | +Is this file converted correctly? |
|
345 | +高髙 |
|
346 | +崎﨑 |
|
347 | +吉𠮷 |
|
348 | +叱𠮟 |
|
349 | +剥剝 |
|
350 | +填塡 |
|
351 | +頬頰 |
|
352 | + タブ制御コード |
|
353 | +``` |
|
354 | + |
|
355 | +# Shift_JIS から UTF16LE(BOM付き)へ変換 |
|
356 | +- [perlでUTF-16LE + BOM - d.aql](http://d.hatena.ne.jp/aql/20090326/1238085344) |
|
357 | +- [Perl 5.8.x 以降で BOM を操作するモジュール ハードなソフトの話/ウェブリブログ](http://hardsoft.at.webry.info/200802/article_2.html) |
|
358 | +- [CPAN:File-BOM](http://search.cpan.org/dist/File-BOM) |
|
359 | +- [convSJIStoUTF16.pl](convSJIStoUTF16.pl) |
|
360 | +```perl |
|
361 | +# convSJIStoUTF16.pl |
|
362 | +# 行単位で加工を行う。 |
|
363 | +# 文字コードを Shift_JIS から UTF-16LE(BOM付き)に変換する。 |
|
364 | + |
|
365 | +use strict; |
|
366 | +use warnings; |
|
367 | +use utf8; |
|
368 | +use Encode; |
|
369 | + |
|
370 | +my $fileNameIn = "Data_SJIS.txt"; |
|
371 | +my $fileNameOut = "Data_UTF16.txt"; |
|
372 | + |
|
373 | +binmode( STDIN, ":encoding(CP932)" ); |
|
374 | +binmode( STDOUT, ":encoding(CP932)" ); |
|
375 | +binmode( STDERR, ":encoding(CP932)" ); |
|
376 | + |
|
377 | +$| = 1; |
|
378 | + |
|
379 | +open( my $fin, "<:encoding(CP932)", encode( 'CP932', $fileNameIn ) ) |
|
380 | + or die( "$fileNameIn: $!\n" ); |
|
381 | +my @body = <$fin>; |
|
382 | +close( $fin ); |
|
383 | + |
|
384 | +$body[ 0 ] =~ /(\s+)$/; |
|
385 | +$/ = $1; |
|
386 | +chomp( @body ); |
|
387 | + |
|
388 | +open( my $fout, ">:raw", encode( 'CP932', $fileNameOut ) ) |
|
389 | + or die( "$fileNameOut: $!\n" ); |
|
390 | +print $fout pack( 'H*', 'fffe' ); # BOMの出力 |
|
391 | +binmode( $fout, ":encoding(UTF16LE)" ); |
|
392 | + |
|
393 | +my $max = scalar( @body ); |
|
394 | +my $count = 0; |
|
395 | + |
|
396 | +while( @body > 0 ){ |
|
397 | + printf STDERR ( "%d/%d\r", ++$count, $max ); |
|
398 | + my $line = shift( @body ); |
|
399 | + # $line =~ s///; # なにか加工を行う。 |
|
400 | + print $fout $line . "\n"; |
|
401 | +} |
|
402 | + |
|
403 | +close( $fout ); |
|
404 | + |
|
405 | +# EOF |
|
406 | +``` |
|
407 | +- UTF-8 BOM の場合 |
|
408 | +```perl |
|
409 | +print $fout pack( 'H*', 'efbbbf' ); |
|
410 | +binmode( $fout, ":utf8" ); |
|
411 | +``` |
|
412 | + |
|
413 | +# ユニコード表示 |
|
414 | +- コマンドラインから渡された文字列のユニコードを表示する。 |
|
415 | +```perl |
|
416 | +#!/usr/bin/perl |
|
417 | +# UTF32 コードの取得 |
|
418 | + |
|
419 | +use strict; |
|
420 | +use warnings; |
|
421 | +use utf8; |
|
422 | +use Encode; |
|
423 | +use Win32::Unicode::Native; |
|
424 | + |
|
425 | +foreach my $arg (@ARGV){ |
|
426 | + foreach my $ch (split(//, $arg)){ |
|
427 | + my $u = unpack('H*', encode('UTF32BE', $ch)); |
|
428 | + $u =~ s/^0*//; |
|
429 | + print "$ch: $u\n"; |
|
430 | + } |
|
431 | +} |
|
432 | +``` |
|
433 | + |
|
434 | +# リンク |
|
435 | +- [[Perl/initConsole]] |
|
436 | +- [[Perl/EPSファイル作成]] |
|
437 | +- [[Perl/ディレクトリの再帰処理]] |
|
438 | + |
|
439 | +- [Unicode support in Perl](http://perldoc.perl.org/perlunicode.html) |
|
440 | + - [Perl における Unicode サポート](http://perldoc.jp/pod/perlunicode) |
|
441 | + |
|
442 | +- [UCSとUTF](http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm) |
|
443 | +- [perl5.8のUnicodeサポート](http://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html) |
|
444 | +- [Perl 5.8.x Unicode関連](http://www.rwds.net/kuroita/program/Perl_unicode.html) |
|
445 | + |
|
446 | +- [Perl の数値変換](http://mikeneko.creator.club.ne.jp/~lab/perl/numerical_transform/) |
|
447 | + |
|
448 | +- [404 Blog Not Found](http://blog.livedoor.jp/dankogai/) |
|
449 | + - [perl, python & ruby - chr() vs. Unicode](http://blog.livedoor.jp/dankogai/archives/50696206.html) |
|
450 | + - [perl, python & ruby - ord() vs. Unicode](http://blog.livedoor.jp/dankogai/archives/50698007.html) |
|
451 | + |
|
452 | +- [文字コードを変換するプログラム(Ruby)](http://itpro.nikkeibp.co.jp/article/COLUMN/20060927/249167/) |
|
453 | + |
|
454 | +- [新常用漢字表が迫るUnicode移行、「シフトJIS」では対応不可能 - 新常用漢字が引き起こす文字コード問題:ITpro](http://itpro.nikkeibp.co.jp/article/COLUMN/20091209/341831/) |
|
455 | + |
|
456 | +- [WikiPedia.ja:バイトオーダーマーク](http://ja.wikipedia.org/wiki/%e3%83%90%e3%82%a4%e3%83%88%e3%82%aa%e3%83%bc%e3%83%80%e3%83%bc%e3%83%9e%e3%83%bc%e3%82%af) |
|
... | ... | \ No newline at end of file |
Perl/\346\227\245\347\265\214ITpro.md
... | ... | @@ -0,0 +1,12 @@ |
1 | +# 日経ITpro |
|
2 | +[[_TOC_]] |
|
3 | +---- |
|
4 | +## いまさら聞けないPerlのお役立ちワザ |
|
5 | +1. [処理系のインストール, エンコーディング, PPM](http://itpro.nikkeibp.co.jp/article/COLUMN/20050829/220194/) |
|
6 | +1. [文字列置換, 正規表現作成](http://itpro.nikkeibp.co.jp/article/COLUMN/20050901/220432/) |
|
7 | +1. [ファイルのリネーム, 実行速度測定](http://itpro.nikkeibp.co.jp/article/COLUMN/20050905/220595/) |
|
8 | +1. [QRコード](http://itpro.nikkeibp.co.jp/article/COLUMN/20050909/220867/) |
|
9 | + |
|
10 | +## Webプログラミング実力アップ |
|
11 | +1. [正しいPerl/CGIの書き方](http://itpro.nikkeibp.co.jp/article/COLUMN/20071011/284280/) |
|
12 | +1. [Webアプリケーション・フレームワーク入門](http://itpro.nikkeibp.co.jp/article/COLUMN/20071011/284283/) |
|
... | ... | \ No newline at end of file |
Perl/\346\233\234\346\227\245\343\201\256\350\250\210\347\256\227(Zeller\343\201\256\345\205\254\345\274\217).md
... | ... | @@ -0,0 +1,64 @@ |
1 | +# 曜日の計算 (Zellerの公式) |
|
2 | +[[_TOC_]] |
|
3 | +---- |
|
4 | +## 概要 |
|
5 | +- ある日付の曜日を計算する。 |
|
6 | +- 計算できるのは、1582年10月15日(金)以降。 |
|
7 | + |
|
8 | +## ソース |
|
9 | +``` |
|
10 | +#!/usr/bin/perl |
|
11 | + |
|
12 | +# 年月日の指定(例:1945年8月15日水曜日) |
|
13 | +$year = 1945; |
|
14 | +$month = 8; |
|
15 | +$day = 15; |
|
16 | + |
|
17 | +$wday = &calcZeller( $year, $month, $day ); |
|
18 | + |
|
19 | +$youbi = ( "Sunday", "Monday", "Tuesday", "Wednesday", |
|
20 | + "Thursday", "Friday", "Saturday" )[ $wday ]; |
|
21 | +$monthname = ( "-", "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
|
22 | + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" )[ $month ]; |
|
23 | +printf( "%s, %02d %s %04d\n", $youbi, $day, $monthname, $year ); |
|
24 | + |
|
25 | +exit(); |
|
26 | + |
|
27 | +# 曜日の計算 |
|
28 | +# @param[in] $year 年 |
|
29 | +# @param[in] $month 月 |
|
30 | +# @param[in] $day 日 |
|
31 | +# @return 曜日 ( 0:日 1:月 2:火 3:水 4:木 5:金 6:土 ) |
|
32 | +sub calcZeller |
|
33 | +{ |
|
34 | + my( $year, $month, $day ) = @_; |
|
35 | + my( $year2, $month2 ) = ( $year, $month ); |
|
36 | + if ( $month == 1 || $month == 2 ) { |
|
37 | + $year2--; |
|
38 | + $month2 += 12; |
|
39 | + } |
|
40 | + return ( $year2 + int( $year2 / 4 ) - int( $year2 / 100 ) + int( $year2 / 400 ) |
|
41 | + + int(( 13 * $month2 + 8 ) / 5 ) + $day ) % 7; |
|
42 | +} |
|
43 | + |
|
44 | +# EOF |
|
45 | +``` |
|
46 | + |
|
47 | +## リンク |
|
48 | +- [曜日 〜Zeller(ツェラー)の公式〜](http://easycgi.xrea.jp/tips/perl/zeller.htm) |
|
49 | +- [WikiPedia.ja:ツェラーの公式](http://ja.wikipedia.org/wiki/%e3%83%84%e3%82%a7%e3%83%a9%e3%83%bc%e3%81%ae%e5%85%ac%e5%bc%8f) |
|
50 | +- [WikiPedia.ja:月_(暦)](http://ja.wikipedia.org/wiki/%e6%9c%88%5f%28%e6%9a%a6%29) |
|
51 | + |
|
52 | +- [AddinBox](http://www.h3.dion.ne.jp/~sakatsu/) / [祝日について](http://www.h3.dion.ne.jp/~sakatsu/holiday_topic.htm) |
|
53 | +- [転倒夢想庵](http://akiba.geocities.jp/tendomusoan/) / [和洋百万年暦](http://akiba.geocities.jp/tendomusoan/100mannenreki.htm) |
|
54 | +- [Internet Mail Consortium](http://www.imc.org/) / [Personal Data Interchange (vCard/vCalendar)](http://www.imc.org/pdi/) |
|
55 | + - [RFC5545 iCalendar](http://www.ietf.org/rfc/rfc5545.txt) |
|
56 | + - [RFC2445 iCalendar](http://www.ietf.org/rfc/rfc2445.txt) |
|
57 | + - [iCalendar 仕様](http://www.asahi-net.or.jp/~CI5M-NMR/iCal/ref.html) |
|
58 | + - [iCal カレンダーライブラリ](http://www.apple.com/jp/ical/library/) |
|
59 | +- [WikiPedia.ja:元号から西暦への変換表](http://ja.wikipedia.org/wiki/%e5%85%83%e5%8f%b7%e3%81%8b%e3%82%89%e8%a5%bf%e6%9a%a6%e3%81%b8%e3%81%ae%e5%a4%89%e6%8f%9b%e8%a1%a8) |
|
60 | + |
|
61 | +- [CPAN:DateTime](http://search.cpan.org/dist/DateTime) |
|
62 | +- [iandeth.](http://iandeth.dyndns.org/mt/ian/) |
|
63 | + - [Perlで日付・時間を操作 - DateTime モジュールの使い方](http://iandeth.dyndns.org/mt/ian/archives/000619.html) |
|
64 | +- [CPAN:Time-Piece](http://search.cpan.org/dist/Time-Piece) |
|
... | ... | \ No newline at end of file |
Perl/\346\234\252\345\256\232\347\276\251\343\202\263\343\203\274\343\203\211\347\275\256\346\217\233.md
... | ... | @@ -0,0 +1,58 @@ |
1 | +# テキストファイル中の Latin-1 未定義コードの置換 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- 置換コードリストに従って、入力テキストファイル中の未定義コードを置換してファイルへ出力する。 |
|
6 | +- コード毎に何件置換したかをレポートする。 |
|
7 | + |
|
8 | +## ダウンロード |
|
9 | +- [replaceCode.zip](replaceCode.zip) |
|
10 | + |
|
11 | +## ソースコード |
|
12 | +``` |
|
13 | +# テキストファイル中の Latin-1 未定義コードの置き換え |
|
14 | + |
|
15 | +use strict; |
|
16 | +use warnings; |
|
17 | +use utf8; |
|
18 | + |
|
19 | +my $infile = "readme.txt"; |
|
20 | +my $outfile = "readme_.txt"; |
|
21 | + |
|
22 | +my %cnvtbl = ( |
|
23 | + 0x91 => '{{', |
|
24 | + 0x92 => '}}', |
|
25 | + 0x93 => '[[', |
|
26 | + 0x94 => ']]', |
|
27 | +); |
|
28 | + |
|
29 | +open( IN, $infile ) || die( "can't open '$infile'.\n" ); |
|
30 | +my @file = <IN>; |
|
31 | +close( IN ); |
|
32 | + |
|
33 | +my $body = join( "", @file ); |
|
34 | + |
|
35 | +my $len = length( $body ); |
|
36 | + |
|
37 | +my ( $i, %codes, $c ); |
|
38 | + |
|
39 | +my $outbody = ""; |
|
40 | + |
|
41 | +for( $i=0; $i<$len; $i++ ){ |
|
42 | + $c = substr( $body, $i, 1 ); |
|
43 | + if ( ord( $c ) > 127 ){ |
|
44 | + $codes{ ord( $c ) } += 1; |
|
45 | + $c = $cnvtbl{ ord( $c ) }; |
|
46 | + } |
|
47 | + $outbody .= $c; |
|
48 | +} |
|
49 | + |
|
50 | +foreach $c ( sort( keys( %codes ) ) ){ |
|
51 | + printf( "%02x: %d\n", $c, $codes{ $c } ); |
|
52 | +} |
|
53 | + |
|
54 | +open( OUT, '>'.$outfile ) || die( "can't open '$outfile'.\n" ); |
|
55 | +print OUT $outbody; |
|
56 | +close( OUT ); |
|
57 | + |
|
58 | +# EOF |
|
... | ... | \ No newline at end of file |
Perl/\347\211\271\346\256\212\346\226\207\345\255\227\343\201\256\343\202\250\343\202\271\343\202\261\343\203\274\343\203\227.md
... | ... | @@ -0,0 +1,92 @@ |
1 | +# 特殊文字のエスケープ |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 注意 |
|
5 | +- HTML のエスケープには encode_entities を使いましょう。([CPAN:HTML-Parser/lib/HTML/Entities.pm](http://search.cpan.org/dist/HTML-Parser/lib/HTML/Entities.pm)) |
|
6 | +- URI のエスケープには uri_escape を使いましょう。([CPAN:URI/URI/Escape.pm](http://search.cpan.org/dist/URI/URI/Escape.pm)) |
|
7 | +- 正規表現をエスケープする時は quotemeta 。([perldoc.jp:func/quotemeta](http://perldoc.jp/func/quotemeta)) |
|
8 | +- SQL は自分でエスケープせず、プレースホルダと bind を使いましょう。 |
|
9 | + |
|
10 | +## 概要 |
|
11 | +- 入力された文字列などの中のHTMLとして直接記述できない文字をエスケープする。 |
|
12 | + |
|
13 | +## ソースコード |
|
14 | +```perl |
|
15 | +#!/usr/bin/perl |
|
16 | +# HTML用にエスケープ処理を行う。 |
|
17 | + |
|
18 | +use strict; |
|
19 | +use warnings; |
|
20 | +use utf8; |
|
21 | +use Encode; |
|
22 | +use HTML::Entities qw( encode_entities ); |
|
23 | + |
|
24 | +my $test = 'He said, "<em>Enjoy & Exciting!</em>."'; |
|
25 | + |
|
26 | +my @subs = ( |
|
27 | + [ 'htmlEscapeN', \&htmlEscapeN, ], |
|
28 | + [ 'htmlEscapeE', \&htmlEscapeE, ], |
|
29 | + [ 'encode_entities', \&encode_entities, ], |
|
30 | +); |
|
31 | + |
|
32 | +printf( "Test:\n%s\n\n", $test ); |
|
33 | +foreach my $s ( @subs ){ |
|
34 | + printf( "%s:\n%s\n\n", $s->[0], &{$s->[1]}($test) ); |
|
35 | +} |
|
36 | + |
|
37 | +exit; |
|
38 | + |
|
39 | +# 数値文字参照(16進)に変換 |
|
40 | +sub htmlEscapeN { |
|
41 | + my( $str ) = @_; |
|
42 | + $str =~ s/([&<>"'])/sprintf( "&#x%02X;", ord( $1 ) )/egmos; |
|
43 | + return $str; |
|
44 | +} |
|
45 | + |
|
46 | +# 文字実体参照に変換 |
|
47 | +# http://blog.livedoor.jp/dankogai/archives/50940023.html |
|
48 | +sub htmlEscapeE { |
|
49 | + my $str = shift or return; |
|
50 | + my %escaped = ( '&' => 'amp', '<' => 'lt', '>' => 'gt', '"' => 'quot' ); |
|
51 | + my $cclass2escape = '[' . join('', keys %escaped) . ']'; |
|
52 | + $str =~ s{(${cclass2escape})(?!amp;)}{'&' . $escaped{$1} . ';'}msxgeo; |
|
53 | + return $str; |
|
54 | +} |
|
55 | + |
|
56 | +# EOF |
|
57 | +``` |
|
58 | + |
|
59 | +## 出力 |
|
60 | +``` |
|
61 | +Test: |
|
62 | +He said, "<em>Enjoy & Exciting!</em>." |
|
63 | + |
|
64 | +htmlEscapeN: |
|
65 | +He said, "<em>Enjoy & Exciting!</em>." |
|
66 | + |
|
67 | +htmlEscapeE: |
|
68 | +He said, "<em>Enjoy & Exciting!</em>." |
|
69 | + |
|
70 | +encode_entities: |
|
71 | +He said, "<em>Enjoy & Exciting!</em>." |
|
72 | +``` |
|
73 | + |
|
74 | +## ユニコード(サロゲートペア)をHTML数値参照へエスケープ |
|
75 | +```perl |
|
76 | +sub escapeSurrogatePair { |
|
77 | + my ($str) = @_; |
|
78 | + $str =~ s/([^\x{0000}-\x{ffff}])/sprintf( "&#x%x;", ord( $1 ) )/egmos; |
|
79 | + return $str; |
|
80 | +} |
|
81 | +``` |
|
82 | + |
|
83 | +## Link |
|
84 | +- [[EscapeSlash|Perl/EscapeSlash]] |
|
85 | + |
|
86 | +- [勝手に添削 - 40行で作るPerl用テンプレートエンジン](http://blog.livedoor.jp/dankogai/archives/50940023.html) |
|
87 | +- [Perlメモ](http://www.din.or.jp/~ohzaki/perl.htm) / [改行コードを統一する](http://www.din.or.jp/~ohzaki/perl.htm#CRLF_Unify) |
|
88 | + |
|
89 | +- [CPAN:HTML-Parser/lib/HTML/Entities.pm](http://search.cpan.org/dist/HTML-Parser/lib/HTML/Entities.pm) |
|
90 | +- [CPAN:URI/URI/Escape.pm](http://search.cpan.org/dist/URI/URI/Escape.pm) |
|
91 | +- [CPAN:String-Util](http://search.cpan.org/dist/String-Util) trim, htmlesc, jsquote |
|
92 | +- [CPAN:Unicode-Escape](http://search.cpan.org/dist/Unicode-Escape) \uXXXX 形式のエスケープ |
|
... | ... | \ No newline at end of file |
Perl/\347\222\260\345\242\203\345\244\211\346\225\260.md
... | ... | @@ -0,0 +1,228 @@ |
1 | +[[_TOC_]] |
|
2 | + |
|
3 | +# 概要 |
|
4 | +- CGIで環境変数を表示します。 |
|
5 | +- 「HTTPS」を表示するように修正。(2012/04/29) |
|
6 | +- 「GeoIP」を表示するように修正。(2012/09/06) |
|
7 | + |
|
8 | +# 動作サンプル |
|
9 | +| HTML版 | [http](http://www.takeash.net/cgi-bin/etc/PrintEnv.cgi) | [https](https://www.takeash.net/cgi-bin/etc/PrintEnv.cgi) | |
|
10 | +| --- | --- | --- | |
|
11 | +| Text版 | [http](http://www.takeash.net/cgi-bin/etc/PrintEnv_txt.cgi) | [https](https://www.takeash.net/cgi-bin/etc/PrintEnv_txt.cgi) | |
|
12 | + |
|
13 | +# ソースコード |
|
14 | +- [PrintEnv.zip](PrintEnv.zip) |
|
15 | + |
|
16 | +## HTML版 |
|
17 | +- [PrintEnv.cgi](http://www.takeash.net/cgi-bin/etc/PrintEnv.cgi) |
|
18 | + |
|
19 | +```perl |
|
20 | +#!/usr/bin/perl |
|
21 | + |
|
22 | +use strict; |
|
23 | +use warnings; |
|
24 | +use utf8; |
|
25 | +use Encode; |
|
26 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
27 | + |
|
28 | +my $charsetConsole = 'UTF-8'; |
|
29 | +my $charsetFile = 'UTF-8'; |
|
30 | + |
|
31 | +binmode( STDIN, ":encoding($charsetConsole)" ); |
|
32 | +binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
33 | +binmode( STDERR, ":encoding($charsetConsole)" ); |
|
34 | + |
|
35 | +my $q = new CGI; |
|
36 | +$q->charset( $charsetFile ); |
|
37 | + |
|
38 | +my $cginame = 'PrintEnv'; |
|
39 | + |
|
40 | +printHeader(); |
|
41 | + |
|
42 | +print $q->start_table( { '-summary' => 'ENV', '-border' => 1 } ); |
|
43 | +print $q->Tr( $q->th( [ 'Key', 'Value' ] ) ); |
|
44 | +foreach ( sort( keys( %ENV ) ) ){ |
|
45 | + if ( /^(GEOIP_|HTTPS|HTTP_|QUERY_|REMOTE_|REQUEST_|SERVER_(ADDR|NAME|PORT|PROTOCOL))/i ){ |
|
46 | + print $q->Tr( $q->td( [ $_, $ENV{$_} ] ) ); |
|
47 | + } |
|
48 | +} |
|
49 | +print $q->end_table(); |
|
50 | + |
|
51 | +printFooter(); |
|
52 | + |
|
53 | +exit; |
|
54 | + |
|
55 | +sub printHeader |
|
56 | +{ |
|
57 | + print $q->header(); |
|
58 | + print $q->start_html( |
|
59 | + '-title' => $cginame, |
|
60 | + '-lang' => 'ja-JP', |
|
61 | + '-head' => [ |
|
62 | + $q->meta( { '-http_equiv' => 'Content-style-type', '-content' => 'text/css' } ), |
|
63 | + $q->meta( { '-http_equiv' => 'Content-script-type', '-content' => 'text/javascript' } ), |
|
64 | + ], |
|
65 | + '-style' => [ { 'src' => '/take.css' }, ], |
|
66 | + ); |
|
67 | + print $q->h1( $cginame ); |
|
68 | +} |
|
69 | + |
|
70 | +sub printFooter |
|
71 | +{ |
|
72 | + print $q->end_html . "\n"; |
|
73 | +} |
|
74 | + |
|
75 | +# EOF |
|
76 | +``` |
|
77 | + |
|
78 | +## Text版 |
|
79 | +- [PrintEnv_txt.cgi](http://www.takeash.net/cgi-bin/etc/PrintEnv_txt.cgi) |
|
80 | + |
|
81 | +```perl |
|
82 | +#!/usr/bin/perl |
|
83 | +# 環境変数の表示(テキスト版) |
|
84 | + |
|
85 | +use strict; |
|
86 | +use warnings; |
|
87 | +use utf8; |
|
88 | + |
|
89 | +print "Content-type: text/plain; charset=UTF-8\n\n"; |
|
90 | + |
|
91 | +foreach ( sort( keys( %ENV ) ) ){ |
|
92 | + if ( /^(GEOIP_|HTTPS|HTTP_|QUERY_|REMOTE_|REQUEST_|SERVER_(ADDR|NAME|PORT|PROTOCOL))/i ){ |
|
93 | + print $_ . "\t" . $ENV{ $_ } . "\n"; |
|
94 | + } |
|
95 | +} |
|
96 | + |
|
97 | +# EOF |
|
98 | +``` |
|
99 | + |
|
100 | +## IIS8用 |
|
101 | +```perl |
|
102 | +#!/usr/bin/perl |
|
103 | +# 環境変数の表示 |
|
104 | + |
|
105 | +use strict; |
|
106 | +use warnings; |
|
107 | +use utf8; |
|
108 | +use Encode; |
|
109 | +use CGI::Pretty qw( -no_xhtml *table ); # //HTML 4.01 Transitional//EN |
|
110 | + |
|
111 | +my $charsetConsole = 'UTF-8'; |
|
112 | +my $charsetFile = 'UTF-8'; |
|
113 | + |
|
114 | +#binmode( STDIN, ":encoding($charsetConsole)" ); |
|
115 | +#binmode( STDOUT, ":encoding($charsetConsole)" ); |
|
116 | +#binmode( STDERR, ":encoding($charsetConsole)" ); |
|
117 | + |
|
118 | +my $encoder = find_encoding( $charsetConsole ); |
|
119 | +if ( defined( $ENV{PERLXS} ) && $ENV{PERLXS} eq 'PerlIS' ){ |
|
120 | + print $encoder->encode( "HTTP/1.0 200 OK\n" ); |
|
121 | +} |
|
122 | + |
|
123 | +my $q = new CGI; |
|
124 | +$q->charset( $charsetFile ); |
|
125 | + |
|
126 | +my $cginame = '環境変数の表示'; |
|
127 | + |
|
128 | +print $encoder->encode(makeHeader($q)); |
|
129 | + |
|
130 | +my $output = ''; |
|
131 | +$output .= $q->start_table( { '-summary' => 'ENV', '-border' => 1 } ); |
|
132 | +$output .= $q->Tr( $q->th( [ 'キー', '値' ] ) ); |
|
133 | +foreach ( sort( keys( %ENV ) ) ){ |
|
134 | + if ( /^(GEOIP_|HTTPS|HTTP_|QUERY_|REMOTE_|REQUEST_|SERVER_(ADDR|NAME|PORT|PROTOCOL))/i ){ |
|
135 | + $output .= $q->Tr( $q->td( [ $_, $ENV{$_} ] ) ); |
|
136 | + } |
|
137 | +} |
|
138 | +$output .= $q->end_table(); |
|
139 | +print $encoder->encode($output); |
|
140 | + |
|
141 | +print $encoder->encode(makeFooter($q)); |
|
142 | + |
|
143 | +exit; |
|
144 | + |
|
145 | +sub makeHeader |
|
146 | +{ |
|
147 | + my $q = shift or return; |
|
148 | + my $ret = ''; |
|
149 | + $ret .= $q->header(); |
|
150 | + $ret .= $q->start_html( |
|
151 | + '-title' => $cginame, |
|
152 | + '-lang' => 'ja-JP', |
|
153 | + '-head' => [ |
|
154 | + $q->meta( { '-http_equiv' => 'Content-style-type', '-content' => 'text/css' } ), |
|
155 | + $q->meta( { '-http_equiv' => 'Content-script-type', '-content' => 'text/javascript' } ), |
|
156 | + ], |
|
157 | + '-style' => [ { 'src' => '/take.css' }, ], |
|
158 | + ); |
|
159 | + $ret .= $q->h1( $cginame ); |
|
160 | + return $ret; |
|
161 | +} |
|
162 | + |
|
163 | +sub makeFooter |
|
164 | +{ |
|
165 | + my $q = shift or return; |
|
166 | + my $ret = ''; |
|
167 | + $ret .= $q->end_html . "\n"; |
|
168 | + return $ret; |
|
169 | +} |
|
170 | + |
|
171 | +# EOF |
|
172 | +``` |
|
173 | + |
|
174 | +## IIS6用 |
|
175 | +```perl |
|
176 | +#!/usr/bin/perl |
|
177 | +# printEnv.pl |
|
178 | +# Linuxの場合は、EUC-JP,LFで保存 |
|
179 | + |
|
180 | +print "Content-type: text/html\n\n"; |
|
181 | + |
|
182 | +print <<EOL; |
|
183 | +<html> |
|
184 | +<body> |
|
185 | +%ENV |
|
186 | +<table border="1"> |
|
187 | +<tr><th>key</th><th>value</th></tr> |
|
188 | +EOL |
|
189 | + |
|
190 | +foreach $key (sort keys(%ENV)){ |
|
191 | + printf("<tr><td>%s</td><td>%s</td></tr>\n", $key, $ENV{$key}); |
|
192 | +} |
|
193 | + |
|
194 | +print <<EOL; |
|
195 | +</table> |
|
196 | +<br> |
|
197 | +%ALL_HTTP |
|
198 | +<table border="1"> |
|
199 | +<tr><th>key</th><th>value</th></tr> |
|
200 | +EOL |
|
201 | + |
|
202 | +# IIS用 |
|
203 | +@ALL_HTTP = split( "\n", $ENV{ "ALL_HTTP" } ); |
|
204 | +%ALL_HTTP = (); |
|
205 | +foreach $line ( @ALL_HTTP ){ |
|
206 | + if ( $line =~ /([^:]+):(.*)\s*/){ |
|
207 | + $ALL_HTTP{ $1 } = $2; |
|
208 | + } |
|
209 | +} |
|
210 | +foreach $key (sort keys(%ALL_HTTP)){ |
|
211 | + printf("<tr><td>%s</td><td>%s</td></tr>\n", $key, $ALL_HTTP{$key}); |
|
212 | +} |
|
213 | + |
|
214 | +print <<EOL; |
|
215 | +</table> |
|
216 | +</body> |
|
217 | +</html> |
|
218 | +EOL |
|
219 | + |
|
220 | +exit(); |
|
221 | + |
|
222 | +# EOF |
|
223 | +``` |
|
224 | + |
|
225 | +# リンク |
|
226 | +- [MaxMind](http://www.maxmind.com/) |
|
227 | + - [mod_geoip2 Apache module](http://dev.maxmind.com/geoip/mod_geoip2) EPEL リポジトリ |
|
228 | + - [GeoLite Databases](http://www.maxmind.com/app/geolite) |
|
... | ... | \ No newline at end of file |
Perl/\350\207\252\345\213\225\343\203\225\343\203\251\343\203\203\343\202\267\343\203\245(\343\203\220\343\203\203\343\203\225\343\202\241\343\203\252\343\203\263\343\202\260)\343\201\256\345\210\266\345\276\241.md
... | ... | @@ -0,0 +1,21 @@ |
1 | +# 自動フラッシュ(バッファリング)の制御 |
|
2 | +``` |
|
3 | +# 自動フラッシュ有効化 (バッファリングを無効化) |
|
4 | +$| = 1; |
|
5 | + |
|
6 | +$end = 10; |
|
7 | + |
|
8 | +for( $i=0; $i<=$end; $i++){ |
|
9 | + printf( "%d/%d\r", $i, $end ); |
|
10 | + sleep(1); |
|
11 | +} |
|
12 | +printf( "\n" ); |
|
13 | + |
|
14 | +# 自動フラッシュ無効化 (バッファリングを有効化) |
|
15 | +$| = 0; |
|
16 | + |
|
17 | +for( $i=0; $i<=$end; $i++){ |
|
18 | + printf( "%d/%d\r", $i, $end ); |
|
19 | + sleep(1); |
|
20 | +} |
|
21 | +printf( "\n" ); |
|
... | ... | \ No newline at end of file |
Perl/\350\241\214\346\234\253\346\224\271\350\241\214\343\201\256\345\211\212\351\231\244.md
... | ... | @@ -0,0 +1,27 @@ |
1 | +# 行末改行の削除 |
|
2 | +[[_TOC_]] |
|
3 | + |
|
4 | +## 概要 |
|
5 | +- ファイルを読み込み、行末改行を一括削除する。 |
|
6 | +- 「CRLF」「LF」のどちらでも対応できるようにする。 |
|
7 | + |
|
8 | +## ソースコード |
|
9 | +``` |
|
10 | +use strict; |
|
11 | +use utf8; |
|
12 | + |
|
13 | +my $fin = "input.txt"; |
|
14 | + |
|
15 | +my @file; |
|
16 | + |
|
17 | +open( IN, "<:utf8", $fin ) || die( "can't open '" . $fin . "'.\n" ); |
|
18 | +@file = <IN>; |
|
19 | +close( IN ); |
|
20 | + |
|
21 | +$file[ 0 ] =~ /(\s+)$/; |
|
22 | +$/ = $1; |
|
23 | +chomp( @file ); |
|
24 | + |
|
25 | +# 実際の処理 |
|
26 | + |
|
27 | +# EOF |
|
... | ... | \ No newline at end of file |