電子書籍の厳選無料作品が豊富!

下記はデレクトリーabcのjpg画像ファイル名を(数字.jpg)
読み込み順に(1.jpg)に変更するコードですが,エラーになります、
#!"C:\perl\bin\perl.exe"
opendir(DIR,"./abc/");# デレクトリopen
@DATA = grep /\.jpe?g/i, readdir(DIR); # デレクトリread
@SDATA = sort { $a cmp $b } @DATA;# ソート
for ($k=0; $k<=@SDATA; $k++) {
$new = $k.'.jpg';
rename ("$SDATA[$k]", "$new");
}
closedir(DIR);
exit;
よろしくお願いします。

A 回答 (4件)

> しかし、画像の枚数が1回実行すると2枚少なくなり


> 再度実行すると今度は6枚少なくなってしまいます

・rename は、変更先と同名のファイルが既に存在していた場合、そのファイルは消えてしまいます。
・cmp は、文字列的にソートしますが、$k.'.jpg' で生成されるファイル名は、ソートすると順番が変わります。

たとえば、0.jpg~12.jpg の13ファイルある場合、
これをソートすると、
0.jpg
1.jpg
10.jpg
11.jpg
12.jpg
2.jpg

9.jpg

という順番になります。
これを、0.jpg~12.jpg にrenameすると、
rename("0.jpg", "0.jpg"); #なにも起きない
rename("1.jpg", "1.jpg"); #なにも起きない
rename("10.jpg", "2.jpg"); #これで、2.jpg が消える
rename("11.jpg", "3.jpg"); #これで、3.jpg が消える
rename("12.jpg", "4.jpg"); #これで、4.jpg が消える
rename("2.jpg", "5.jpg"); #これで、5.jpg が消える
以下略

といったことになります。
ファイルが消えるのを防ぐためには、
・作業用のディレクトリを作成し、対象ファイルを一旦そちらに移動する
などの操作が必要があります。
---ここから---
$tempdir = "tempdir".$$;
$num=0;
while (-d $tempdir) {
$tempdir = "tempdir".($num++);
}
mkdir($tempdir);
foreach(@SDATA) {
rename("./abc/$_", "$tempdir/$_");
}
for ($k=0; $k<@SDATA; $k++) {
$new = $k.'.jpg';
rename ("$tempdir/$SDATA[$k]", "./abc/$new");
print "rename '$SDATA[$k]', '$new'\n";
}
rmdir($tempdir);
---ここまで---
といった感じで。
    • good
    • 0
この回答へのお礼

何度も回答ありがとうございます、
参考書にも書いていないことを分かりやすく
回答していただき感謝いたします、
ファイルが消滅する理由がよくわかりました。

お礼日時:2009/06/18 18:36

> エラーの明細です。



CGIで実行しているんですね。
だったら、CGIとして正しい出力をしておかないとダメです。
冒頭(#!の次の行あたり)に
> print "Content-Type: text/plain\n\n";
とでも追加してみてください。
ついでに、rename の次に
> print "rename '$SDATA[$k]', '$new'\n";
とでも入れておけば、どのファイルを処理しようとしているのか表示されて状況が分かりやすくなるかと思います。

この回答への補足

再度の回答ありがとうございます
下記のコ-ドで実行するとエラーは出なくなりました、
しかし、画像の枚数が1回実行すると2枚少なくなり
再度実行すると今度は6枚少なくなってしまいます、
よろしくお願いします。
#!"C:\perl\bin\perl.exe"

print "Content-Type: text/plain\n\n";
opendir(DIR,"./abc/");#デレクトリopen
@DATA = grep /\.jpe?g/i, readdir(DIR); #デレクトリread
@SDATA = sort { $a cmp $b } @DATA; #ソート
for ($k=0; $k<@SDATA; $k++) {
$new = $k.'.jpg';
rename ("./abc/$SDATA[$k]", "./abc/$new");
print "rename '$SDATA[$k]', '$new'\n";
}
closedir(DIR);
exit;

補足日時:2009/06/17 20:55
    • good
    • 0

具体的にどういうエラーが出ているのかわかりませんが、



> for ($k=0; $k<=@SDATA; $k++) {
これだとループの終了条件が1回多いです。$k < @SDATA にしないと。
(配列の要素数@SDATAに対し、添字は0~(@SDATA-1)。

> rename ("$SDATA[$k]", "$new");

readdir が返すのはファイル名だけで、ディレクトリ名は含みません。ですから、
> rename ("./abc/$SDATA[$k]", "$new");
と、ディレクトリも指定する必要があります。
(上記コードだと、変更後のファイルはカレントディレクトリに移動します。ディレクトリを移動させたくないなら、変更後のファイル名も "./abc/$new" にしてください。)

この回答への補足

回答ありがとうございます、エラーの明細です。
Server error!
The server encountered an internal error and was unable to complete your request.
Error message:
Premature end of script headers: henkou.cgi
If you think this is a server error, please contact the webmaster.
Error 500
miwaku99.ddo.jp
06/16/09 17:46:41
Apache/2.2.6 (Win32) DAV/2 mod_ssl/2.2.6 OpenSSL/0.9.8e mod_autoindex_color PHP/5.2.4

補足日時:2009/06/16 17:47
    • good
    • 0

で, どんなエラーメッセージなのか見せてくれないんですか?

    • good
    • 0

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