マンガでよめる痔のこと・薬のこと

以下のようなファイル名が複数あります。

abcd_021106_0.txt
abcd_021106_1.txt
abcd_021106_2.txt
abcd_021106_11.txt

これを @list = glob("abcd_021106_*");で
取得すると、配列には、

(0) abcd_021106_0.txt
(1) abcd_021106_1.txt
(2) abcd_021106_11.txt
(3) abcd_021106_2.txt

というふうに格納されてしまいます。
これではまずいので、きちんと末尾の順番どおり
sort するには どのようにすればいいのでしょうか。
よろしくご指南ください。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

急いで書いたので可読性が悪く、極意と言うほど一般化できませんでしたが、下記で出来ますよ。


ファイル名の形式が、「文字列_数字_数字.拡張子」となっている場合しか使えません。
形式が違う場合は、正規表現と、<=>、cmpを入れ替えて使ってください。


@orglist = glob("abcd_021106_*");

foreach (@orglist) {
my ($nofi) = $_ =~ m/^(\w+)\.\w+$/;
push(@tmplist, [$_, split("_", $nofi)]);
}
@newlist = sort {$a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] || $a->[3] <=> $b->[3]} @tmplist;
@list = ();
foreach (@newlist) {
push(@list, $_->[0]);
}

この時点で、@listに期待した順番でファイル名が入っているはずです。
    • good
    • 0
この回答へのお礼

スクリプトまでご紹介くださり、ありがとうございます。
そのまま貼り付ける形で実行できることを確認しました。
貴重な時間を割いていただき、感謝いたします。

お礼日時:2002/11/07 14:28

ご要望のソートは、次のスクリプトで実現できます。


  @list = map {$_->[0]}                    # 3
        sort {$a->[1] <=> $b->[1]}           # 2
          map {[$_,/^abcd_\d{6}_(\d+)/]} @list;   # 1
これは、
1.元データと末尾の数値からなる"無名配列のリスト"を生成
2.末尾の数値で"無名配列のリスト"をソート
3.ソートされた"無名配列のリスト"から、元データを取り出す
という流れになっています。

ファイルの命名規則が「名前_日付_番号.txt」となっているようですので、これを「名前順 かつ 日付順 かつ 番号順」でソートする場合、次のようにします。
  @list = glob("*_*_*.txt");     # globのパターンも変える
  @list = map {$_->[0]}
        sort {$a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] || $a->[3] <=> $b->[3]}
          map {[$_,/^([a-z]+)_(\d{6})_(\d+)/]} @list;

アルゴリズムについては、参考URLのページもご参考ください。

参考URL:http://www.din.or.jp/~ohzaki/perl.htm#SortST
    • good
    • 0
この回答へのお礼

スクリプトと詳細に解説していただき、ありがとう
ございます。ご紹介いただいた URL も 大いに参考に
なりました。自分でも探したつもりでしたが、見つける
ことができませんでした。
貴重な時間を割いていただき、感謝いたします。

お礼日時:2002/11/07 14:31

ソートですが、下記のものが正しいですね。


そうならないように以下のように工夫してもらうしかないです。

(0) abcd_021106_00.txt
(1) abcd_021106_01.txt
(2) abcd_021106_02.txt
(3) abcd_021106_11.txt

以上のように桁数をあわせてあげれば、あなたが思ったようにソートされます。
    • good
    • 0
この回答へのお礼

ありがとうございます。
このようなフォーマットにするのが正当なんですね。
以後、参考にさせていただきます。

お礼日時:2002/11/07 14:26

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

Qcgiとplとpm

掲示板ソースをダウンロードするとplやpmという拡張子のものがありました。中身はPerlでした。
拡張子の使い分けを教えてください。

適当に4つのルールを書いてみましたので、間違っていたり、追加するルールがありましたから教えてください。

1 ブラウザがそれ自身にアクセスし、ブラウザのアドレスバーに表示させるならcgiにするべき。

2 Perlのpackageの機能を使うなら、パッケージファイルはplかpmでなくてはならない。

3 Perlのrequireの機能を使うなら、その外部ファイルはplでなくてはいけない。

4 Perlのuseの機能を使うなら、その外部ファイルはpmでなくてはならない。

Aベストアンサー

基本的に拡張子は、あっても無くてもなんでもOKです。ただ、モジュールには.pmをつけなければなりません。
また、webサーバによってCGIとして使える拡張子に制限がある場合があります。

1.について
言語として、特に拡張子を.cgiにしなければならないというのはありません。.plでも.doでも.hoge
でも基本的には大丈夫ですが、大抵運用するwebサーバによって使える拡張子が制限されています。.cgiしかダメなサーバとか。

2.について
そのような制限はありません。拡張子は何でもOKです。
ただ、前述の通りwebサーバによって拡張子の制限がかかっている場合はCGIとしては実行できません。

3.について
そのような制限はありません。拡張子は何でもOKです。

4.について
その通りです。use関数の対象になる外部ファイルは.pmでなければなりません。

Qreaddir()で得られるファイル・ディレクトリ情報の順番は?

Perlプログラムにて、

 opendir(DIR, '.');
 @dir_list = readdir(DIR);
 closedir(DIR);

などとすると、そのディレクトリにあるファイルとディレクトリの一覧情報を得ることができますが、この場合、@dir_list にはどのような順番で情報が格納されるのでしょうか?

readdir() 関数の仕様が知りたいです。ご存知の方、ぜひ教えてください。

Aベストアンサー

仕様という意味ではこちらになるでしょうね。
公式サイトですから。
http://www.perl.com/doc/manual/html/pod/perlfunc/readdir.html

同じような疑問を持たれた方がおられるようなので、載せておきます。
http://www.computing.net/programming/wwwboard/forum/4535.html

ここではファイルシステム依存ということになっていましたが、公式サイトには順番についての記述はありませんでした。

したがって、
> どのような順番で情報が格納されるのでしょうか?
の答えは「決まっていない」になりますね。
処理系依存ということでしょう。

どんな環境でも同じ結果が欲しいというのであれば、@dir_listに対してsortをかけるしかないと思います。

参考URL:http://www.perl.com/doc/manual/html/pod/perlfunc/readdir.html

QCan't use string ("0") as an ARRAY ref の原因について

Perl 5.6を使っております。
Perlで原因不明なエラーに直面して困っております。
Can't use string ("0") as an ARRAY ref while "strict refs"
というエラーが発生しているのですが
これは良くあるミスとして何が原因でしょうか?

Aベストアンサー

No.2です。書き漏らしてましたが、エラーメッセージの内容がよくわからない時は

use diagnostics;

しましょう。

QCPANでインストールしたモジュールの削除方法

CPANであるモジュールをインストールしたのですが見当違いのモジュールでした。
削除しなければならず色々調べてみたのですがインストール方法しか見つからず削除方法がわかりません。

どなたかわかる方教えてください。

Aベストアンサー

がると申します。
uninstallは、install方法次第ではあるのですが。
もしcpanコマンド使ってであるとすると、それは実際にはMakefileでのコンパイル&installになります。
で。
make install系の、これは最大の欠点といわれているのですが。「自力で手動で探し出す以外に削除手段はない」です。
# rpm系の唯一にして最大の利点がココの部分の解消ですね。

cpanでのinstallですと、どこか(多分 /root あたり)に.cpan/build/というディレクトリがありまして、その下にソースが展開されているので。
ソースはそこから。.soファイルは…Makefile解析するか、findあたりで探すか、で削除するしかないです。
確か、メジャーなcpanのMakefileはそんなにお行儀悪くないので、そうあちこちには散らかしてないと思うのですが…。

また不明な点などあったら追加で質問していただければ。

Qperlで配列の要素が空なのを知るには?

教えてください。

例えば、perlの次の様な要素が3つある配列で、

@t = ('A',,'C');

2要素目が空で有ることを判別したいのですが、どうしたら良いでしょうか?

Aベストアンサー

'' と比較する.

Qperlで配列名を動的に作り出したい

試しに次のようにしてみましたがエラーになりました。

#!/usr/local/bin/perl
use strict;
use warnings;
my $mystr = "abcde";
my @{$mystr} = (1,2,3);

$mystrの内容はいろい変わっていきます。

ご存知の方いらっしゃいましたらすみませんが教えてください。
よろしくお願いいたします。

Aベストアンサー

なんでそんなことをしたいんですか?
ハッシュと無名リストへのリファレンス使って
my %a =() ;
$a{$mystr}=[1,2,3] ;
とかやった方がいろいろ便利だと思うんですが。
・変数名に使えない文字を$mystrに使える
・keys,each,exists等のハッシュを操作する関数が使える

Qpingでポートの指定

pingでIPアドレスを指定して、通信できるかどうかというのは
よく使いますが、pingでポートを指定して応答するかどうかは調べられるのでしょうか?

よろしくお願いします

Aベストアンサー

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含むICMP)ではできません。

FTPの疎通確認であれば、クライアントからサーバに対するTCP/21通信(FTP-CMD)が可能であること(サーバからクライアントへのTCP/21からの応答を含む)+サーバからクライアントに対するTCP/20通信(FTP-DATA)が可能であること(クライアントからサーバへのTCP/21からの応答を含む)が必要でしょう。

監視ソフトによるものであれば、
・クライアントからサーバへのログイン(TCP/21)
・クライアントからサーバへのlsの結果(TCP/20)
で確認すればよいでしょう。

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含む...続きを読む


人気Q&Aランキング