chdirがうまくできない

このQ&Aのポイント
  • WindowsXP&Cygwin環境でchdirがうまくできない問題が発生しています。ディレクトリ移動が正常に行われず、ファイル処理ができません。
  • dir.txtからサブディレクトリ名を読み取り、そのディレクトリに移動し、ファイル処理をする必要がありますが、移動できていない状況です。
  • ディレクトリ移動に関してテキストの扱い方が間違っている可能性があります。直接ディレクトリ名を指定した場合は正常に移動できることから、テキストの読み取り方法が問題と考えられます。
回答を見る
  • ベストアンサー

chdirがうまくできない

はじめまして。hiro0777と申します。 perl初心者です。 お恥ずかしい内容なのですが、アドバイスいただければと思います。 環境はWindowsXP&Cygwinです。 質問内容:chdirがうまくできない。(ディレクトリ移動がうまくいかない) ・カレントディレクトリには、いくつかのサブディレクトリがあり、  サブディレクトリ名のみが書かれたファイル(dir.txt)がある。  dir.txtには「480iacrlc2」「480iacscan」といったディレクトリ名が1行ずつ記載。 ・dir.txtから1つずつサブディレクトリ名を読み取り、  そのディレクトリに移動し、ファイル処理をする。 #ここでコマンド引数にdir.txtを指定。 open(DIR, $ARGV[0]) || die "can't open $ARGV[0]\n"; while(1){ chomp($dir = <DIR>); #print "$dir\n"; chdir("$dir") or die "Cannot change directory '$dir'\n"; #system("pwd");  ###以降ファイル処理。 } 上記のようにやったのですが、うまくディレクトリを移動してくれません。 ちなみに以下のように直接ディレクトリ名を指定した場合はうまくいきました。 open(DIR, $ARGV[0]) || die "can't open $ARGV[0]\n"; while(1){ $dir = "480iacrlc2";#ファイル名を直接指定したら移動した。 chdir("$dir") or die "Cannot change directory '$dir'\n"; #system("pwd");  ###以降ファイル処理。 } テキストの扱いかたがいけないのかなぁと想像しているのですが。 どなたかご教授いただければ幸いです。 よろしくお願いいたします。

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

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

while ループの中身が終わったときに chdir で元のディレクトリに戻らないといけないとか, そんなオチかなぁ.... とりあえず ・ディレクトリ構造 ・dir.txt の中身 ・どの chdir で失敗するか を書いてもらえますか?

hiro0777
質問者

お礼

Tacosanさん、ご回答ありがとうございました。 自己解決できました。 結論は、Cygwin上の文字コードの問題でした。 http://perl.g.hatena.ne.jp/Cress/20070226 内容としては上記のようなものになります。 お騒がせしました。以上です。

関連するQ&A

  • ディレクトリ内のテキストファイルに対する同一処理

    よろしくお願いします。現在Linuxの環境でテキスト処理をしております。 ディレクトリ内にファイル名の異なった以下のような大量ファイルがあります。 a.txt 0,1,2,3,4,5,6,7 1,2,3,4,5,6,7,8 b.txt 2,3,4,5,6,7,8,9 3,4,5,6,7,8,9,10 これらのファイルをカンマでsplitし、左から2番目の数にだけ1を引き,下のディレクトリであるoutに出力させます。出力は以下のようになります。 ./out/a.txt 0,0,2,3,4,5,6,7 1,2,3,4,5,6,7,8 ./out/b.txt 2,2,4,5,6,7,8,9 3,4,5,6,7,8,9,10 そこで以下のようなPerlのプログラムを作成しました。 use strict; use warnings; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); print $dir, "\n"; open(FILE, $dir) or die "$dir: $!"; my @file = <FILE>; foreach $line (@file) { my ($a,$b,$c,$d,$e,$f,$g,$h) = split(/,/, $line);      my $b = $b - 1; close(FILE); } open(NEWFILE, "> ./out/$dir") or die "$dir: $!"; print NEWFILE @file; close(NEWFILE); } closedir(DIR); ですが、出力は完了するのですが、元のファイルから計算がされていません。どこがどう間違えているのかご指摘よろしくお願い申し上げます。

    • ベストアンサー
    • Perl
  • 下のディレクトリ(3つ)に含まれる同じファイル名のテキストを結合し,カレントディレクトリに出力する

    いつもお世話になっております.環境はWindows XPのActiveperlです. やりたいことは「下のディレクトリ(3つ)に含まれる同じファイル名のテキストを結合し,カレントディレクトリに出力する」ことです.具体的にはいかのようにしたいと思っています. 現在のディレクトリ/a/1.txt a b c 現在のディレクトリ/b/1.txt d e f 現在のディレクトリ/c/1.txt g h i 現在のディレクトリ/1.txt a b c d e f g h i ここで私は以下のプログラムを作成しました. use strict; use warnings; my $dirname1 = './a/'; my $dirname2 = './b/'; my $dirname3 = './c/'; opendir(DIR1, $dirname1) or die "$dirname1: $!"; while (my $dir1 = readdir(DIR1)) { next unless (-f $dir1); next unless ($dir1 =~ /\.txt$/); opendir(DIR2, $dirname2) or die "$dirname2: $!"; while (my $dir2 = readdir(DIR2)) { next unless (-f $dir2); next unless ($dir2 =~ /\.txt$/); opendir(DIR3, $dirname3) or die "$dirname3: $!"; while (my $dir3 = readdir(DIR3)) { next unless (-f $dir3); next unless ($dir3 =~ /\.txt$/); if (($dir1 == $dir2) && ($dir2 == $dir3)){ open(FILE1, $dir1) or die "$dir1: $!"; my $line1 = <FILE1>; close(FILE1); open(FILE2, $dir2) or die "$dir2: $!"; my $line2 = <FILE2>; close(FILE2); open(FILE3, $dir3) or die "$dir3: $!"; my $line3 = <FILE3>; close(FILE3); my $joint_line = $line1.$line2.$line3; open(NEWFILE, "> $dir1") or die "$dir1: $!"; print NEWFILE $joint_line; close(NEWFILE); } } } } closedir(DIR1); closedir(DIR2); closedir(DIR3); ですが,以下のようなエラーが発生しています. closedir() attempted on invalid dirhandle DIR2 at joint.pl line 51. closedir() attempted on invalid dirhandle DIR3 at joint.pl line 52. ディレクトリハンドルが使われているけれど閉じているか実際にはディレクトリハンドルでは無い時にこれらの警告が発行されるとこの警告がでるようですが,どのようにしたら解決できるのでしょうか.よろしくお願いします.

  • awkの正規表現について

    ディレクトリ名とファイル名の一覧ファイルがあり、その中から特定ディレクトリの1階層下のディレクトリ名とファイル名を取得したいのですが、うまく抽出できません。 ディレクトリ名とファイル名の一覧ファイル(dir.txt)は /foo/ /foo/bar/ /foo/bar/a.txt /foo/bar/sub/ /foo/bar/sub/x.txt /foo/var/ /foo/var/b.txt /usr/ /usr/bar/ で「/foo/」指定すると /foo/ /foo/bar/ /foo/var/ を抽出し 「/foo/var/」を指定すると /foo/var/ /foo/var/b.txt を抽出したいです。 この場合、awk '$1 ~ /^\/foo\/bar\// {print}' dir.txtとすると /foo/bar/ /foo/bar/a.txt /foo/bar/sub/ /foo/bar/sub/x.txt が抽出されてしまいます。 どのような書き方をすれば1階層下のディレクトリとファイルのみを 抽出できるのでしょうか?

  • csvファイルを統合する

    あるディレクトリにtest1.txtとtest2.txtというカンマ区切り(拡張子はcsvではないですけど)があったとして、それらのファイルを1行ずつ読み込み、それを追加書き出しで1つのファイルに収めていこうとしています。 そこで以下のようなコードを書いてみたのですが、どうやらtest1.txtしか読み込んで書き出せていないようなのです。その原因が分からずに困っています。 $dir = 'C:/Perl/workdir'; # 対象ディレクトリ名 open MYHANDLE, ">>out.txt"; # 追加書き出しモードでファイルハンドルをオープン opendir DH, $dir or die "$dir:$!"; # ディレクトリを開く while ($file = readdir DH) { # ディレクトリにあるファイル名を取得し、$fileに格納 next if $file =~ /^\.{1,2}$/; # '.'や'..'も取れるので、スキップする open MYFILE, "$file"; # 取得したファイルを開く while (<MYFILE>) { chomp; @dat = split /,/; # 読み込むファイルは「カンマ区切り」としてレコードを読み込む。 $n = @dat; for($i=0; $i<$n; $i++){ print MYHANDLE $dat[$i]; # ファイルに追加書き出し(ファイルがなければ新規作成される) print MYHANDLE ","; # カンマ区切りで書き出していく } print MYHANDLE "\n"; # 1行読み終えるごとに改行 } close MYFILE; # i番目のファイルを読み終えたら閉じる print $file, "\n"; # 読み込み・書き出しをしたファイル名を表示する } closedir DH; close MYHANDLE;

    • ベストアンサー
    • Perl
  • テキストを参照としたPerlによる名前の変更

    よろしくお願いします。ディレクトリ内のファイル名をテキストデータを参照として変更したいと思っております。まず、以下の参照テキストがあります。 sansyo.txt 1,2,1 2,3,1 3,4,2 4,5,3 6,7,9 ・ ・ ・ ・ このファイルを利用してディレクトリ内のファイルを以下のようにリネームします。 1,2.txt → 1,2,1.txt 2,3.txt → 2,3,1.txt 3,4.txt → 3,4,2.txt 4,5.txt → 4,5,3.txt 6,7.txt → 6,7,9.txt ・ ・ ・ ・ ・ ここで私は以下のプログラムを作成しました。 sansyo.pl ------------------------------ use strict; use warnings; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); print $dir, "\n"; open(FILE, $dir) or die "$dir: $!"; open(FILE2,"sansyo.txt"); my @file = <FILE>; my @file2 = <FILE2>; close(FILE); close(FILE2); foreach my $line2 (@file2) { my ($a,$b,$c) = split(/,/, $line2); if ($dir == $a.",".$b.".txt"){ rename ($dir, $a.",".$b.",".$c.".txt"); } } } closedir(DIR); 内容は、FILE2にsansyo.txtをforeachで1行ずつ読み込んでいき、 $a,$b.txtというファイルが$dirに読み込んだファイルにあったら、 $a,$b,$c.txtというファイルにリネームするという内容です。 ですが、いろいろ試行錯誤したもののうまくいきません。 具体的には、 Argument "1,2.txt" isn't numeric in numeric eq (==) at sansyo.pl line 23. とエラーがでて if ($dir == $a.",".$b.".txt"){ この部分でエラーが発生しているようです。 どなたか解決方法をよろしくお願いします。

    • ベストアンサー
    • Perl
  • プログラムの高速化

    いつもお世話になっております.以下のプログラムをできるだけ高速化したいと思います. use warnings; use strict; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); open(FILE, $dir) or die "$dir: $!"; while (my $line = <FILE>) { my ($a,$b,$c,$d,$e,$f) = split( /,/ , $line ); my $name = $a.",".$b; open(NEWFILE, ">> ./out/$name.txt") or die "$dir: $!"; print NEWFILE $line; close(NEWFILE); } } close(FILE); closedir(DIR); やっていることは,ディレクトリ内のテキストファイルを読み込んでいって,splitでカンマ区切りにした,$a,$bをファイル名として下のディレクトリのoutに保存していくというものです. ファイル数が数千あり,各ファイルも数千行となるため,このソースを高速化する方法はありますでしょうか.ご回答よろしくお願いします.

    • ベストアンサー
    • Perl
  • Windows漢字フォルダ名の扱い(chdir編)

    先回、次の質問をさせて頂いた者です。http://oshiete1.goo.ne.jp/qa2230450.html 今回、同様な環境にて、chdir()実行しようとすると、 D:\temp ├─フォルダ名の末尾に機能 ├─フォルダ名の末尾に表 ├─途中に機能がある └─途中に表がある スクリプト内では、次のように書いています(サブルーチン部) sub dir_recurs { my $sdir = @_; my ($d,$rc); my $cwd = Cwd::getcwd(); opendir(DIR,$sdir) || die "$cwd/$sdir") . " $! stopped"; my @dirs=(); my @files=(); foreach(sort readdir(DIR)){ if( -d "$_/" ){ next if(/^\.+/); # '.' '..' はパス push(@dirs,"$_"); }elsif( -f "$_" ){ push(@files,$_); # ディレクトリ以外有り }else{ print "ERROR: '$_' in $cwd.\n"; } } closedir(DIR); #----- 下位ディレクトリへ潜る if(@dirs > 0){ foreach $d (@dirs){ if(!chdir("$d/")){ print "ERROR: chdir($d) from $cwd\n"; next; } $rc = &dir_recurs("."); chdir(".."); } } : 前後関係は、はしょりますが、この処理部が走っているときに、 ERROR: 'temp.txt' in D:\temp\フォルダ名の末尾に機・ ERROR: chdir(フォルダ名の末尾に表) from 'D:\temp' ERROR: chdir(途中に機能がある) from 'D:\temp' ERROR: chdir(途中に表がある) from 'D:\temp' のような結果になってしまいます。 一番先頭でのエラーメッセージを見る限りは、 一度は、「D:\temp」の下の「フォルダ名の末尾に機能」ディレクトリに 潜ることを成功しているようなのですが、次回以降に失敗しています。 この症状について、理由等、お分かりの方、よろしくお願いいたします。

  • Windows漢字フォルダ名の扱い(その2)

    先回に引き続きお伺いします。 ■フォルダツリー体系が次のようになっているとき、 D:\TEMP ├─フォルダ名の末尾に機能 │ test1.txt ├─フォルダ名の末尾に表 │ test2.txt ├─途中に機能がある │ test3.txt └─途中に表がある test4.txt ■次のスクリプトを処理させるのですが、 #!perl use strict; &subdir($ARGV[0]); sub subdir { my($dir) = $_[0]; opendir(DIR,"$dir") || die "'$dir' $! stopped"; foreach(sort readdir(DIR)){ next if(/^\.+/); # '.' '..' はパス if(-f "$dir\\$_"){ print "'$dir\\$_'\tはファイルです\n"; }elsif(-d "$dir\\$_"){ print "'$dir\\$_'\tはフォルダです\n"; &subdir("$dir\\$_"); }else{ print "'$dir\\$_'\tは何ですか?\n";#出て欲しくない } } closedir(DIR); } ■結果は、次のようになります。 (※フォルダ名の末尾に特殊な漢字コードがある所が判定できない) C:\>test.pl d:\temp 'd:\temp\フォルダ名の末尾に機能' は何ですか? 'd:\temp\フォルダ名の末尾に表' は何ですか? 'd:\temp\途中に機能がある' はフォルダです 'd:\temp\途中に機能がある\test3.txt' はファイルです 'd:\temp\途中に表がある' はフォルダです 'd:\temp\途中に表がある\test4.txt' はファイルです 先回、色々と教わったこと use encoding "Shift_JIS"; や 局所的に $dir を decodeさせるなどしても上手く行きません。良い方法があれば教えてください。

    • ベストアンサー
    • Perl
  • 一つのテキストファイルと複数のファイルの結合

    よろしくお願いします.ディレクトリ内の一つのテキストファイル(joint.txt)と複数のファイルの結合を行ごとに隣へ結合するプログラムを作成しています.ここで以下のプログラムを作成したのですが,うまくいかないため,誤っている部分をご指摘願えないでしょうか. my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); open(FILE, $dir) or die "$dir: $!"; open(FILE2,"joint.txt"); my @file = <FILE>; my @file2 = <FILE2>; close(FILE); close(FILE2); foreach my $line (@file) { foreach my $line2 (@file2) { chomp $line2; $line = "$line2.",".$line"; } } open(NEWFILE, "> $dir") or die "$dir: $!"; print NEWFILE @file; print NEWFILE @file2; close(NEWFILE); } closedir(DIR);

    • ベストアンサー
    • Perl
  • foreachの入れ子について。

    あるディレクトリ内の全てのファイル名を取得し、 全てのファイルを開いてカンマ、ダブルクォーテーション付加の処理をし、 別ファイルへと出力する。と言ったものを以下のように作ったのですが、 入れ子のforeach{}内へ入って行きません、 foreachの入れ子は出来ないのでしょうか? それともプログラムが間違っているのでしょうか? どなたかご教授お願いいたします。 require "./jcode.pl"; # jcode.plの呼び出し #ディレクトリ表示 opendir(DIR01,"./TestData") || die "can not open dir"; @FileName = readdir(DIR01); closedir(DIR01) || die "can not close dir"; foreach $file (@FileName) { if ($file eq '.') {next;} # '.'の時ループを抜ける if ($file eq '..') {next;} # '..'の時ループを抜ける $FName = "./TestData/$file"; # ファイルのオープン open ( FILEHANDLE , "$FName") || die "ファイルを開けません :$!\n"; @line = <FILEIN>; close (FILEIN); foreach $line (@line){ ######################### print "TEST-->$line\n"; ######################### $line =~ s/ⅰ|ⅱ|ⅲ|ⅳ|ⅴ|ⅵ|ⅶ|ⅷ|ⅸ|ⅹ//g; $line =~ s/\"/\"\"/g; $line =~ s/\,\"\?/\"\,\"/g; $line =~ s/\"\,\?/\"\,\"/g; $line =~ s/\ |\ /\"\,\"/g; &jcode::sjis2euc(\$line,"z"); # sjis --> euc コードへ変換 if (length $line != 1){ chop($line); $cd_22 = chr(0x0022); $line = "$cd_22$line$cd_22"; $line =~ s/([^\LF])$/$1\n/; } } open (FILEOUT, ">./log/TEST.txt") or die; #上書き時 print FILEOUT @line; close (FILEOUT); } } exit;

    • ベストアンサー
    • Perl

専門家に質問してみよう