• ベストアンサー

ファイル名の抜き出しについて

いつもお世話になります。 ファイルアップロードし、アップロードしたファイル名を記録するプログラムを 作成しております。(ファイル名を記録し、別プログラムでファイル名にリンクを張ります。) この中でアップロードファイル名がc:\temp\cgi\test.cgiやc:\mydocument\test\temp\cgi\test.cgiと いったものも含め実ファイル名(test.cgi)のみを抜きだして記録したいのですが、上手くいきません。 ファイル名を切り出す方法を教えていただきましたが、こちらも上手くいきませんでした。 $inLink =~ s/^.*[\\\/]//;と記述。 どなたかご教示お願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.8

#7>$inLINK =~ s/^.*\\//;を解説していただければ助かります。 #1の方が書いていらっしゃるように、ファイル名以外の部分を取り除きます。 変数 =~ s/パターン/置き換える文字列/; は、変数でパターンにマッチングした部分を"置き換える文字列"で置き換えます。 ^ は、先頭を表すパターンで .* は、一文字の0回以上の繰り返しパターン \\ は、円マーク\ ですが、\ 自体が次のパターン文字をパターンとして認識させないという機能を持つ記号なので、\\のように2つ続けて書く必要があります。 つまり、先頭から、\までを"何もない"と置き換える、即ち取り除くという意味になります。 この場合、.* は、より長くマッチしようとするので、フォルダの階層が深くて \ マークが複数在った場合でも最後の \ マークまで取り除くことができます。

cardy55
質問者

お礼

BLUEPIXY様おはようございます。無理なお願いに対応していただきありがとうございました。おかげさまで理解が進みました。BLUEPIXY様含め今回の件は皆さんに感謝いたします。本当にありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (7)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.7

#5補> >$inLink =~ /(^.*\\)(.*)/; >open(OUT, "> ../upload/$inLINK"); は、ダメです。 >$inLink =~ /(^.*\\)(.*)/; の部分では、s/…/…/をしていませんから、マッチングをさせているだけですから$inLink は置き換えられていません。 マッチングが成功した場合には open(OUT, "> ../upload/$2"); のようにすればいいと思います。 また、$inLink を置き換えた場合には >open(OUT, "> ../upload/$inLINK"); の$inLINK は、"LINK" が大文字になっているため別の変数になっています。同じ変数名を使う必要があります。

cardy55
質問者

補足

BLUEPIXY様:回答が遅れて申し訳ありません。変数名の件お恥ずかしながらミスでした。ご指摘ありがとうございます。冷静な目が必要ですね 。結局下記のようにして動作いたしました。沢山の方々にサポートしていただき助かりました。不勉強で申し訳ありませんが、~ /(^.*\\)*)/;を解説していただければ助かります。 if ($inLINK ne '') { while ($bytesread = read($inLINK, $buffer, $BUFSZ)) { $file .= $buffer; } $inLINK =~ s/^.*\\//; open(OUT, "> ../upload/$inLINK"); binmode(OUT); print(OUT $file); close(OUT); }

すると、全ての回答が全文表示されます。
noname#19175
noname#19175
回答No.6

use strict; を使われることをおすすめします。 Perlでは大文字と小文字を区別しますから。 basenameが使えないのもこれで解消できればいいのですが、、、 私が知ってる各OSのデリミタは UNIX(UNIX like OS) / Windows(DOS) \ (ドライブとパスの区切りに:を使用) Mac Classic : MacOS X / です。 私はデリミタで分割して最後の部分を取り出してましたけどね(^^; Perlの場合は、 if(($pos=rindex($inLink,'/'))>=0){ $inLink = substr($inLink, $pos+1); }elsif(($pos=rindex($inLink,'\\'))>=0){ $inLink = substr($inLink, $pos+1); }elsif(($pos=rindex($inLink,':'))>=0){ $inLink = substr($inLink, $pos+1); } print $inLink; こんな感じで出来たと思いますが、正規表現で不要部分を消しちゃった方がスマートかも(^^; ファイル名の取得方法はどのようにされてますか? <form action="" method="post" enctype="multipart/form-data"> で送信されている場合は、 filename=~ という行が書き出されますが、このときのファイル名は、 ブラウザがデリミタを変更する場合もあるので、クライアントのOSに関係なく、すべてをチェックした方が良いと思います。

cardy55
質問者

補足

taloo様ご回答ありがとうございます。 とりあえずuse strict;を使用してみます。 それから下記部分のご解説をお願いします。 form action="" ~はご指摘の通り記述しております。 「filename=~で書き出される」、「クライアントのOSに関係なく~」の箇所が不勉強で理解できませんでした。 -------------------------------------------------- <form action="" method="post" enctype="multipart/form-data"> で送信されている場合は、 filename=~ という行が書き出されますが、このときのファイル名は、 ブラウザがデリミタを変更する場合もあるので、クライアントのOSに関係なく、すべてをチェックした方が良いと思います。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

#3>basenameが上手く動作していないみたい う~ん、なんでですかね~。 #3がうまくいかないのは、OS間でファイルパスの記述が異なるからかもしれませんけど、 #1,2,4でうまくいかない理由がわからないですね。 本当に、切り出そうとしている $inLink にc:\mydocument\test\temp\cgi\test.cgi のような文字列が入っているんでしょうか?

cardy55
質問者

補足

BLUEPIXY様おはようございます。何度もテストしました。例えばC:\TEMP\CGI\test\upload4\readme.txtファイルを切り出そうと思い下記記述をしてみましたが、上手くいっておりません。ファイルは「C:\TEMP\CGI\test\upload4\readme.txt」でアップロードされファイル名は記録されていません。 $BUFSZ = 2048; $file = ''; $buffer = ''; if ($inLINK ne '') { while ($bytesread = read($inLINK, $buffer, $BUFSZ)) { $file .= $buffer; } $inLink =~ /(^.*\\)(.*)/; open(OUT, "> ../upload/$inLINK"); binmode(OUT); print(OUT $file); close(OUT); } --------------------------------------- ファイル記述は下記の通りです。 seek(DATA, 0, 0); print DATA $tNum."\n"; print DATA @tData; print DATA $tNum."<>".$inTITLE."<>".$inMAIN."<>".$inDATE."<>".$inSEL."<>".$inLink."<>".$inFLAG."<>".$inCATE."\n"; truncate(DATA, tell(DATA)); close(DATA); &unlock; 私では手に負えません。ヒントなどなんでも結構ですので教えて下さい。

すると、全ての回答が全文表示されます。
  • okiyoshi
  • ベストアンサー率34% (11/32)
回答No.4

use strict; my $up_file = 'c:\mydocument\test\temp\cgi\test.cgi'; # としたとき、 my $up_file_name = ( split /[\/\\]/, $up_file )[-1]; print "$up_file_name\n";

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

use File::Spec; $file=q(c:\temp\test.txt); ($volume, $directories, $filename)=File::Spec->splitpath($file); print "$filename\n"; か use File::Basename; $filename = basename($file); print "$filename\n";

cardy55
質問者

補足

BLUEPIXY様ご回答ありがとうございます。テストしてみましたが、ファイル名が入りませんでした。どうやらbasenameが上手く動作していないみたいです。環境の設定などございますでしょうか? プログラムの先頭付近にuse File::Basename;を記述し、 ファイル名を書き込み所で$filename = basename($file);を記述しております。

すると、全ての回答が全文表示されます。
  • ttyp03
  • ベストアンサー率28% (277/960)
回答No.2

#1です。 もうひとつこんなのを。 $inLink =~ /(^.*\\)(.*)/; print "$2\n"; こっちのほうが抜き出してる感じですかね。

すると、全ての回答が全文表示されます。
  • ttyp03
  • ベストアンサー率28% (277/960)
回答No.1

こんなんですかねぇ。 $inLink =~ s/^.*\\//; でもこれだと切り出すというよりは余計な部分を削除してるだけですが。

cardy55
質問者

補足

ttyp03様ご回答ありがとうございます。テストしていた為回答が遅くなりました。色々やってみたのですが、ファイル名が変わりませんでした。c:\mydocument\test\temp\cgi\test.cgi等をアップロードするとそのまま(c:\mydocument\test\temp\cgi\test.cgiという風に)記録されてしまいます。クライアントは(windows多数、MACも多少あり。)サーバーはlinuxです。引き続きサポート願えれば幸いです。

すると、全ての回答が全文表示されます。

関連するQ&A