2017年7月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

Amazonウィジェット

  • miniPC
  • 最近買った本
  • Raspberry Pi
  • クアッドコプター
  • 書籍ランキング

AdSense

  • 広告
無料ブログはココログ

Perl

2014年3月18日 (火)

Perl 数値変換やビット演算のテクニック

バイナリデータをいじる機会があったので、こちらの情報を頼りにいくつかの処理を試した。

エクセルでも分析ツールをインストールすれば下記のような操作も可能ではあるが、データが膨大であるしセルにいちいち並べるのがどうしても気に食わないのでPerlを使いたかった。

いろいろ試してみたところ、書き方ひとつで正しい答えにならなかったり、pack unpackがいまいち意味不明だったりで、あまり頻繁にやりたいものではないなと感じた。一度作って動いたら絶対いじりたくないというジャンル・・・。


使用したもの:activeperl 5.16.3 Build1603(64bit)

#16進数4桁データ。
$val = "42CC";
print "$val\n";


#1byte以上の場合は頭に"0x"をつけてやらないと、16進データとみなしてくれなかった。
$val = "42CC";
$str = '0x' . "$val";
$val = hex($str);
print "$val\n";


#ビット演算したければ、バイナリが一番簡単。Hexは上手くいかなかった。
$val1 = "11111111";
$val1 &= "00110000"; # ANDを取る
print "$val1\n";


#HEXを2進数に変換する方法。

#まずは基本の使い方。
$res = unpack("B*", "\x33");
print "$res\n";


#2桁の場合は1バイトずつ区切りが必要。

$res = unpack("B*", "\xFF\xCC");
print "$res\n";


#ビット演算をする場合
$val = unpack("B*", "\xFF\xCC");
$res = $val & "1100110000000000";
print "$res\n";


#ビット演算してからDECに変換
#このやり方はお勧めしない。BCDとして使うならよし。

$val = unpack("B*", "\xFF\xFF");
$val &= "0000000000000011"; #ビット演算をした。
print 'val=' . "$val\n";
@ress = unpack("C*",  pack("B16","$val")); #8桁ずつ変換されてしまう。
print $ress[0] .','.$ress[1] . "\n";


#ビット演算してからHEXに変換
$val = unpack("B*", "\xFF\xFF");
$val &= "0000000000000011"; #ビット演算をした。
print 'val=' . "$val\n";
$res = unpack("H*",  pack("B16","$val")); #8桁ずつ変換
print 'res=' . $res . "\n";

#ついでにHEX to DECの変換
$dec = hex($res);
print 'dec=' . $dec . "\n";


2014年3月 2日 (日)

Perl Fileをドラッグアンドドロップでまとめて処理する

Perlを使うと単純作業を大量にこなすことが簡単になるが、コマンドラインからファイルを指定するのが結構面倒だったりする。ドラッグアンドドロップで処理ができれば一番いい。
これを実現するための雛形を作っておいた。

使用バージョン
ActivePerl 5.12.4 (64bit)
windows7(64bit) SP1

まず、こんな雛形スクリプトを書いた。
「fileBatch.pl」をダウンロード

----------------------------

use strict;
use warnings;

for my $file (@ARGV){
	
	print "$file\n";
}
my $in = <STDIN>;

----------------------------

最初のstrictやwarningsは、Perlにエラーや警告を発してもらうためのもの。

@ARGVはコマンドライン引数のリスト。$ARGV[0]だとコマンドライン引数の最初の一個だけ受け取る。
※これはC言語のargv[0]では少し違っていて、実行ファイルの名前が出てくる。

for文(foreachを使ってもいい)を使ってコマンドライン引数で受け取ったファイルを一個ずつ順番に$filenに取り出し、ループの中のprintで中身を標準出力している。

最後に<STDIN>でキー入力待ちをしている。
リターンキーを押すまでプログラムを一旦停止させることができる。

このままだとコマンドライン(cygwinの例)からこんな風にして使わないといけない。
$ perl ./fileBatch.pl tame.csv tame2.csv tame3.csv

これをD&Dでやれるようにしようとすると、バッチファイルに一旦受けて、そのバッチファイルからPerlを実行する方法がある。しかしバッチファイルを使うことがあんまりないので少々書くのが億劫になる。

こんなときのためにPerlスクリプトをバッチファイルに変換してくれるツールがついている。
ActivePerlのインストールフォルダのbinに、pl2bat.batというバッチファイルが存在する。

このバッチファイルに変換したいPerlスクリプトをD&Dすると、簡単に生成できる。
スクリプトを実行するときは生成されたバッチファイルに先ほどのtame.csvファイル群をD&Dしてやるとよい。

出来たファイル
「fileBatch.bat」をダウンロード

ところで、このバッチファイルにドラッグアンドドロップすると、ドロップしたファイルの絶対パスのリストが表示される。何かキーを押すと終了。

生成されたバッチファイルの中にあるFOR文のところに好きな処理を書いたり他のスクリプトを実行するようにすれば、ドロップしたファイルを対象に色々な処理をさせることができる。