いぜん二重引用符("")と一重引用符('')は微妙に機能が違うという話をしました。
今日はバッククォート(``)を紹介します。JISキーボードだとPの右、@をShiftと押すと出てきます。USキーボードだと一番左上、1の左。ASCII文字コードは0x60です。
Perlではこれが、OSのコマンドをこれで囲むと戻り値がリストで戻ってくるというものすごい便利な機能を持っています。

今日はバッククォート(``)を紹介します。JISキーボードだとPの右、@をShiftと押すと出てきます。USキーボードだと一番左上、1の左。ASCII文字コードは0x60です。
Perlではこれが、OSのコマンドをこれで囲むと戻り値がリストで戻ってくるというものすごい便利な機能を持っています。

次のコードはlsコマンドを使って「大きさが200バイト台の2月に書いた.plで終わるファイルの一覧」を表示します。
実行します。
どうですか。
シェルスクリプトよりも複雑なロジックを書くのが簡単で、ここぞというときにOSのコマンドを使えるので超便利だと思います。
正規表現も当然使えます。
ではなぜ『かんたんPerl』で取り上げなかったかというと、可搬性(ポータビリティ)がないからです。要は1つのOSでしか動きません。OSのコマンドを呼んでいるから当然です。で、Windowsではこうなります、UNIXではこうなります、と書いていたらボーダイな記述になってしまうんです。
Windowsで似たようなプログラムを書くとこうなります。
全然違いますね。そもそもコマンドがlsとdirで違うし、日付がFebだったり02だったり、サイズがWindowsはカンマ編集されてたりします。実行します。
およ、実行結果も違いますね。これはプログラムではなくて環境のせいで、Dropboxの更新のタイミングが違うのでこうなりました。日付はどっちも最終更新日付です。
これ、Perl自力でも、opendir、readdir、stat関数を使えば出来ます。
Macで実行。
Windowsで実行。
まったく同じプログラムが両方のOSで出来ました。ls/dir程度であれば、ちゃんとPerlの機能だけ使ってやった方がいいですね。でも、ちょっとしたカレンダーを請求書の頭に出したいとかで
と書いただけで
とか書けるのは素敵じゃないですか。
#! /usr/local/bin/perl
#
# backTick.pl -- バッククォートのテスト
use strict;
use warnings;
use 5.010;
my @ls = `ls -al *.pl`;
# 0 1 2 3 4 5 6 7 8
# -rwxr-xr-x@ 1 query1000 staff 217 Jan 7 18:49 testUnpack.pl
for (@ls) {
my ($size, $month, $day, $name) = (split)[4, 5, 6, 8];
say "$name $month $day $size bytes" if 200 <= $size and $size < 300 and $month eq "Feb";
}
#
# backTick.pl -- バッククォートのテスト
use strict;
use warnings;
use 5.010;
my @ls = `ls -al *.pl`;
# 0 1 2 3 4 5 6 7 8
# -rwxr-xr-x@ 1 query1000 staff 217 Jan 7 18:49 testUnpack.pl
for (@ls) {
my ($size, $month, $day, $name) = (split)[4, 5, 6, 8];
say "$name $month $day $size bytes" if 200 <= $size and $size < 300 and $month eq "Feb";
}
実行します。
[sample]$ ./backTick.pl
decHex.pl Feb 3 209 bytes
forSqrt.pl Feb 1 223 bytes
ourVar3.pl Feb 5 212 bytes
[sample]$
decHex.pl Feb 3 209 bytes
forSqrt.pl Feb 1 223 bytes
ourVar3.pl Feb 5 212 bytes
[sample]$
どうですか。
シェルスクリプトよりも複雑なロジックを書くのが簡単で、ここぞというときにOSのコマンドを使えるので超便利だと思います。
正規表現も当然使えます。
ではなぜ『かんたんPerl』で取り上げなかったかというと、可搬性(ポータビリティ)がないからです。要は1つのOSでしか動きません。OSのコマンドを呼んでいるから当然です。で、Windowsではこうなります、UNIXではこうなります、と書いていたらボーダイな記述になってしまうんです。
Windowsで似たようなプログラムを書くとこうなります。
#! /usr/local/bin/perl
#
# backTickW.pl -- バッククォートのテスト(Windows版)
use strict;
use warnings;
use 5.010;
my @dir = `dir *.pl`;
# 0 1 2 3
# 2015/12/30 11:14 217 testUnpack.pl
for (@dir) {
next unless m{^2016/02};
my $size = (split)[2];
$size =~ s/,//g;
print if 200 <= $size and $size < 300;
}
#
# backTickW.pl -- バッククォートのテスト(Windows版)
use strict;
use warnings;
use 5.010;
my @dir = `dir *.pl`;
# 0 1 2 3
# 2015/12/30 11:14 217 testUnpack.pl
for (@dir) {
next unless m{^2016/02};
my $size = (split)[2];
$size =~ s/,//g;
print if 200 <= $size and $size < 300;
}
全然違いますね。そもそもコマンドがlsとdirで違うし、日付がFebだったり02だったり、サイズがWindowsはカンマ編集されてたりします。実行します。
C:\Users\cf\NEWDR\Dropbox\kpc\sample>backTickW.pl
2016/02/03 10:48 209 decHex.pl
2016/02/05 22:00 212 ourVar3.pl
2016/02/03 10:48 209 decHex.pl
2016/02/05 22:00 212 ourVar3.pl
およ、実行結果も違いますね。これはプログラムではなくて環境のせいで、Dropboxの更新のタイミングが違うのでこうなりました。日付はどっちも最終更新日付です。
これ、Perl自力でも、opendir、readdir、stat関数を使えば出来ます。
#! /usr/local/bin/perl
#
# fileSearch.pl -- ファイルの検索
use strict;
use warnings;
use 5.010;
opendir DIR, ".";
while (readdir DIR) {
next unless /\.pl$/;
my ($size, $time) = (stat "$_")[7, 9];
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
say "$_ $mon/$mday ${size}bytes" if 200 <= $size and $size < 300 and ++$mon == 2;
}
closedir DIR;
#
# fileSearch.pl -- ファイルの検索
use strict;
use warnings;
use 5.010;
opendir DIR, ".";
while (readdir DIR) {
next unless /\.pl$/;
my ($size, $time) = (stat "$_")[7, 9];
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
say "$_ $mon/$mday ${size}bytes" if 200 <= $size and $size < 300 and ++$mon == 2;
}
closedir DIR;
Macで実行。
[sample]$ ./fileSearch.pl
decHex.pl 2/3 209bytes
forSqrt.pl 2/1 223bytes
ourVar3.pl 2/5 212bytes
decHex.pl 2/3 209bytes
forSqrt.pl 2/1 223bytes
ourVar3.pl 2/5 212bytes
Windowsで実行。
C:\Users\cf\NEWDR\Dropbox\kpc\sample>fileSearch.pl
decHex.pl 2/3 209bytes
ourVar3.pl 2/5 212bytes
decHex.pl 2/3 209bytes
ourVar3.pl 2/5 212bytes
まったく同じプログラムが両方のOSで出来ました。ls/dir程度であれば、ちゃんとPerlの機能だけ使ってやった方がいいですね。でも、ちょっとしたカレンダーを請求書の頭に出したいとかで
#! /usr/local/bin/perl
#
# calPrint.pl -- カレンダーの表示
use strict;
use warnings;
use 5.010;
print `cal`;
#
# calPrint.pl -- カレンダーの表示
use strict;
use warnings;
use 5.010;
print `cal`;
と書いただけで
[sample]$ ./calPrint.pl
February 2016
Su Mo Tu We Th Fr Sa
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
[sample]$
February 2016
Su Mo Tu We Th Fr Sa
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
[sample]$
とか書けるのは素敵じゃないですか。