ファイル名変更ができません

このQ&Aのポイント
  • Perl初心者の質問です。フォルダ内のファイル名を変更するスクリプトを実行したいが、エラーが発生して上手くいきません。
  • 使用している環境はWindows XP professional SP3とActivePerl 5.10です。
  • 既存のファイル名を「filename_ja.txt」から「filename_en.txt」に変更したいが、エラーメッセージが表示されファイルが消失してしまいます。
回答を見る
  • ベストアンサー

ファイル名変更ができません

こんにちは。Perl(超?)初心者です。 フォルダ内にあるファイルの名前を、「filename_ja.txt」という形式から「filename_en.txt」に変更するスクリプトを書こうとしているのですが、エラーになってうまくいきません。 環境は、Windows XP professional SP3とActivePerl 5.10 で、以下のように記述しました。 use strict; use warnings; my @filename = glob "*.txt"; foreach my $oldname(@filename) { my $newname = $oldname; $newname = ~s/(.+)_ja\.txt/$1_en\.txt/; rename ($oldname,$newname); } これを実行すると、「Use of uninitialized value $_ in substitution (s///) at test_5.pl line 8.」とエラーメッセージが出て、フォルダ内のテキストファイルが消失してしまいます。 また、以下のようにも書いてみたのですが、やはりうまくいきません。 この場合は、エラーこそ出ないものの、なにも起こりません。 use strict; use warnings; for(<\.txt>) { my $old=$_; s/(.+)_ja\.txt/$1_en\.txt/; rename($old,$_); } 初歩的な質問で申し訳ありませんが、ダメな生徒にアドヴァイスを与えるつもりで、スクリプトを添削していただけるとありがたいです。 よろしくお願いします。

  • Perl
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.1

$1_en\.txt を、 ${1}_en\.txt に代えたらどうでしょう? 一般的に、 "" や m// の様な変数と文字列を混在して書ける所では、変数名の終りを意識せずに書くと後続の文字列も含めて変数名と解釈される場合があります。 そのときは、上記の様に変数名を {} で囲みましょう。 ところで... > $newname = ~s/(.+)_ja\.txt/$1_en\.txt/; = と ~ の間に空白は、本当は無いんですよね? 「=~」はひとつの演算子で、途中の空白は無い方が良いです。 「=~」の前後には、空白がある方が良いです。 ところで その2 $newname =~ s/_ja\.txt$/_en\.txt/; の方が良いと思いますよ。

Kazu_creator
質問者

お礼

早速のご回答ありがとうございました。 ご指摘のとおり、= と ~ の間にスペースがあり、ついでに =~ の後ろにスペースがありませんでした。ここを直したら、意図したとおりに動きました。 ところで、ファイル名を変更したいファイルは「en」というファルダに入っているのですが、このフォルダ名を引っ張ってきて、「_ja.txt」を「_en.txt」にすることは初心者にも可能でしょうか。 というのも、C:\foldername\en、C:\foldername\de、C:\foldername\frという3つのフォルダに大量のファイルが格納されていて、それぞれ「en」フォルダのファイルは「_en.text」に、「de」は「_de.txt」に、「fr」は「_fr.txt」にファイル名を変更する必要があるのです。 これを処理するスクリプトは、初心者にはハードルが高すぎるでしょうか。 想像するに、C:\foldername 以下のディレクトリ名を取得して、そこから最後の2文字を切り出して、それを配列やら変数やらに代入してなどなど、難しそうな作業が満載のような気がします。

その他の回答 (2)

  • kuroizell
  • ベストアンサー率55% (95/170)
回答No.3

条件の後出しは(スクリプト書く上で)非常に嫌われるので、最初に出来る限り出しておいたほうがいいですよ。 use strict; use warnings; use File::Copy; my $dir = "C:/foldername"; my @langs = qw/en de fr/; foreach my $lang (@langs) { while (my $file = glob "$dir/$lang/*.txt") { my $rename = $file; $rename =~ s/_jp\.txt$/_$lang.txt/; move ($file, $rename); } }

  • zxcv0000
  • ベストアンサー率56% (111/196)
回答No.2

> 初心者にも可能でしょうか。 やりたい事がもっと詳細かつ具体的に分らないと何とも言えませんね。 Perl初心者というよりプログラミング初心者ならなおさらです。 ・C:\foldername は例なんでしょうが、1個だけか沢山あるのか? ・対象ファイルは、C:\foldername/*/ 直下のみかサブディレクトリ下にもあるのか? まずは、 glob に絶対パスを渡して簡単になりませんか? glob "C:/foldername/en/*_ja.txt" とか glob "C:/foldername/*/*_ja.txt"

Kazu_creator
質問者

お礼

ご助言ありがとうございます。 glob に絶対パスを渡すこともできるのですね。 それなら、 my @filename = glob "C:/foldername/en/*_ja.txt" <ファイル名変更の処理> my @filename = glob "C:/foldername/de/*_ja.txt" <ファイル名変更の処理> my @filename = glob "C:/foldername/fr/*_ja.txt" <ファイル名変更の処理> のように、重ねていけばいけそうな気がします。 土臭いやり方ですけど。

関連するQ&A

  • C言語を使用し、同じ内容のファイルを増やす

    始めまして、ちょっと困っている事があります。 今現在Cで、あるプログラムを作ってます。 さて困っている内容ですが、testと記述されているテキストファイルを増やす所で困ってます。 「test」と記述されている「test.txt」を記述内容は同じで 「test01.txt」「test.02.txt」「test03.txt」・・・ と増やすにはどのようにプログラムを書けば宜しいでしょうか? *因みに、こちらが作成してみたプログラムです。 renameを使用して元のファイルを変えていく感じでやっていましたが・・ #include <stdio.h> #define MANGA 10 /*int main(void) { char oldname[256] = "bace00.html", newname[256] = "bace01.html"; FILE *fp; int i,a; printf( "%s\n", newname ); for( a = 0; a < MANGA; a++ ){ printf( "%d",a ); printf( "%s\n", newname ); rename(newname, "bace02.html"); printf( "%sあああ\n", newname ); //rename(oldname, newname) //newname[256] = "bace"; for( i = 0; i < MANGA; i++ ){ fp = fopen( "bace00.html","w" ); fprintf( fp, "<html>\n<title>%s</title>\n<head>\n</head>\n</html>\n" ); fclose( fp ); */ /* ファイル名の変更 */ /* if (rename(oldname, newname) == 0){ printf("%s のファイル名を %s に変更しました。\n", oldname, newname); }else{ perror("rename error"); } } } return 0; }*/

  • apple scriptファイル名の一部のみ変更

    apple scriptにおいて、ファイル名変更の自動化を試みています。 ファイル名にabcという文字が含まれる場合、それらをdefに 変更する、というようなことがしたいのですが、 (001abc.txt -> 001def.txt 003abc0.txt -> 003def0.txt) apple scriptにおいて set oldName to name of aObj --- newNameを指定 set name of aObj to newName の上記でoldNameからnewNameをどう得たらよろしいでしょうか?

    • ベストアンサー
    • Mac
  • perl use strict; と ファイルハンドルについて

    perl use strict; を使うと、単純なエラーが防げると認識していますが、下記スクリプトでは役に立たなかったようで、このエラーを探すのに苦労しました。 他にも、どこかのサブルーチンでsortを使ったスクリプト中で、$aを使った時もおかしな挙動をしたことがあります。 use strict;の使い方は正しいと思うのですが、エラーを出してはくれないものでしょうか? また、このようなエラーをしないために安全なプログラムの書き方はありますか? use strict; open(F,"<file.txt"); while(<F>){ &abc($_); } close(F); sub abc(){ my $str = shift @_; open(F,">>file2.txt"); print F $str; close(F); }

    • ベストアンサー
    • Perl
  • フォルダ内のファイルを全て開き文字列置換

    こんばんは。Perl超初心者です(プログラミングの初心者でもあります)。 フォルダ内にあるすべてのファイルに対して、正規表現を使った文字列置換をしたいのですが、うまくいきません。アドヴァイスをいただけないでしょうか。 具体的には、あるファルダの中に100個程のファイルがあって、その中の改行が3回連続している部分を、「改行+[SAMPLE]+改行」に置換をしたいと表います。 Windows XP Professional SP3 / ActivePerl 5.10 の環境で、以下のように記述したのですが、「Missing $ on loop variable at insert.pl line 5.」とエラーになってしまいます。どこで、間違ったのでしょうか(というか、まるでダメなスクリプトかもしれませんが…)。 use strict; use warnings; my @filename = glob "*.txt"; foreach open(FILE, "$filename(@filename)") { my @content =<FILE>; @content =~ s/\n{3}/\n[SAMPLE]\n/g; print FILE @content; close(FILE); } どなたか、ご教示いただけると非常助かります。 よろしくお願い致します。

    • ベストアンサー
    • Perl
  • 別名で保存し、元の名前で中身を新しくして使いたい

    個人名.xlsmがあり、中味をみて必要ならばまっさらのに更新し、元の分はOLDというフォルダに保存したいのですが... oldName=ThisWorkbook.Name oldPath=ThisWorkbook.Path 中味をみて更新すべきという状態だったら newName="以前の" & oldName newPath=oldPath & "\" & "OLD" ThisWorkbook.save as Filename:=newPath & "\" & newName sheets("sheet1").select Cells.Select Selection.ClearContents ThisWorkbook.save as Filename:=oldPath & "\" & oldName とすると最後の行が黄色になって、 実行時エラー 1004 個人名.xlsmにアクセスできません。 とでます。 何か打開する方法はないでしょうか?

  • Perl:ドイツ語のウムラウト文字の置換ができなくて困っています

    Perl初心者です。ドイツ語のウムラウト文字の置換ができなくて困っています。 環境はWindowsXP + ActivePerl v.5.8.7 です。 以下のスクリプトを実行しています。 === use strict; use warnings; use encoding 'utf8'; my $txt = "*"; print "Pre: $txt\n"; $txt =~ s/*/a/; #置換 print "After: $txt\n"; === *にアルファベットや日本語を入れたときは、"a"に置換されるのですが、 ドイツ語の"アーウムラウト"を入れると置換されません。 文字コードを調べたりしたのですが、解決策が見つからずにこまっています。 きっと、基本的なことがわかっていないのだと思います。 お助けください。

    • ベストアンサー
    • Perl
  • 配列内定義サブルーチン呼び出し

    下記のような配列内定義サブルーチン呼び出しを作成し動作を確認しました。 次にソース2行目の「no strict;」を「use script;」に変更すると Bareword "sub1" not allowed while "strict subs" in use at refsub_OK.pl line 4. Bareword "sub2" not allowed while "strict subs" in use at refsub_OK.pl line 4. Bareword "sub3" not allowed while "strict subs" in use at refsub_OK.pl line 4. Execution of refsub_OK.pl aborted due to compilation errors. とエラーになります。 プログラムはやはり「use script;」を記述したいのですが、「use script;」を記述 したままでエラーにならない方法がありましたらおしえてください。 perlのバージョンは5.12.3、OSはWindowsXP SP3です。 よろしくお願いします。 ---ソースここから--- #!perl no strict; use warnings; my @ary = ( ("input1.txt", "save1.txt", sub1), ("input2.txt", "save2.txt", sub2), ("input3.txt", "save3.txt", sub3), ); while (@ary) { my $p1 = shift(@ary); my $p2 = shift(@ary); my $sub = shift(@ary); print "p1=[$p1] p2=[$p2] sub=[$sub]\n"; &$sub("$p1", "$p2"); } sub sub1 { my ($p1, $p2) = @_; print "sub1: [$p1] [$p2]\n"; } sub sub2 { my ($p1, $p2) = @_; print "sub2: [$p1] [$p2]\n"; } sub sub3 { my ($p1, $p2) = @_; print "sub3: [$p1] [$p2]\n"; } ---ソースここまで---

    • ベストアンサー
    • Perl
  • ファイルからデータを読み込んで配列に格納するには

    読んでいただいてありがとうございます。 Perlをはじめたばかりなのと プログラミング自体もまだまだですので 困っております。 テキストデータ 例えば apple りんご banana バナナ orange オレンジ などというファイルから読み込んで、 my $data ={ my @english, my @japanese, }; などの、配列の構造体に格納するにはどのようにしたら よいのでしょうか。 最初、本を少し読んだだけの知識で、 use strict; use warnings; my $filename = 'data.txt'; my $data = { my @english, my @japanese }; open(IN,$filename) or die "$filename: $!"; while(my $line=<IN>){ for(my $i=0;$i<N;$i++){ ($data->{@english}[$i],$data->{@japanese}[$i])=split(/ /,$line); print "$data->{@english}[$i]\n"; } } close(IN); } などと書いて、 apple banana orange と表示されるのを期待したのですが、 ダメでした。 参考までに私の誤ったプログラムものせましたが、 全然違っているかもしれませんので、まったく新たに アドバイスしていただいてもかまいません。 これを応用したものを使いたいので ぜひともどなたかお教え いただければと思います。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • ファイル名を正規表現にかける際の文字コードについて

    Windows XP, ActivePerl5.8.8 です。 windows 上にあるファイルの名前に沿ってフォルダに振り分けしたく、 以下のようなコードを書きましたが、 ファイル名に日本語の「ソ」などがある場合に 処理がおかしくなります。 文字コードの問題だと思いますが、どうすれば解決できるでしょうか。 ++++ここからソース++++++ #!c:/perl/bin/perl.exe use 5.008; use strict; use warnings; use File::Basename; use File::Copy; use File::Path; my $newdir = "C:/tmp"; for my $filename ( @ARGV ){ main($filename); print "complete.\n"; } sub main{ my ($filename) = @_; my($basename, $basedir) = fileparse($filename); my($name1, $name2, $ext) = $basename =~ /^(.*) - (.*)(\.[a-zA-Z0-9]+)$/; mkdir "${newdir}/${name1}"; File::Copy::copy( "${filename}", "${newdir}/${name1}/${basename}" ) or die "${filename} : Cannot copy"; } 1;

    • ベストアンサー
    • Perl
  • perlで配列名を動的に作り出したい

    試しに次のようにしてみましたがエラーになりました。 #!/usr/local/bin/perl use strict; use warnings; my $mystr = "abcde"; my @{$mystr} = (1,2,3); $mystrの内容はいろい変わっていきます。 ご存知の方いらっしゃいましたらすみませんが教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • Perl

専門家に質問してみよう