2008-03-16から1日間の記事一覧

9.11 8進数ではなく記号でパーミッションを操作する

Stat::IsModeを使用すると、数値形式のパーミッションを記号形式のパーミッションに変換できる。 use Stat::IsMode; $lsmode = file_mode($pathname); File::chmodを使用すると、記号形式のパーミッションを操作できる。 use File::chmod; chmod("g=rw, o=-w…

9.10 ファイル名を構成要素に分解する

フルパスから、ファイルの名前、ファイルを格納しているディレクトリの名前、拡張子を抽出したい。 FIle::Basenameモジュールを使用する use File::Basename; $base = basename($path); $dir = dirname($path); ($base, $dir, $ext) = fileparse($path);

9.9 ファイル名を変更する

foreach関数とrename関数を使用する。 foreach $file (@NAMES) { my $newname = $file; # $newnameを変更する処理を書く rename($file, $newname) or warn; }

9.8 ディレクトリとその中身を削除する

File::FIndモジュールのfinddepth関数を使用する。 例. rmtree1 #!/usr/bin/perl -w # rmtree1 - ディレクトリツリー全体を削除する(rm -rと同等) use File::Find; die "usage: $0 dir ..\n" unless @ARGV; find { bydepth => 1, no_chdir => 1, wanted => s…

9.7 ディレクトリ内の全てのファイルを再帰的に処理する

File::Findモジュールを使用する use File::Find; sub process_file { # 任意の処理を書く } find(\&process_file, @DIRLIST);

9.6 パターンにマッチするファイル名のリストを取得する

glob関数、もしくは<>演算子を使用する。 @list = <*.c>; @list = glob("*.c"); readdir関数を使用してファイル名を手動で抽出する opendir(DIR, $path); @files = grep { /\.c$/ } readdir(DIR); closedir(DIR);

9.5 ディレクトリ内の全てのファイルを処理する

opendir関数でディレクトリをオープンし、readdir関数で各ファイル名を取り出す。 opendir(DIR, $dirname) or die; while (defined($file = readdir(DIR)) { # "$dirname/$file"に対する処理を書く } closedir(DIR);

9.4 同じファイルに2つの名前が与えられていないか確認する

リスト内の2つのファイル名がディスク上の同じファイルに対応していないかどうか確認したい(ハードリンク、ソフトリンクにより、2つのファイル名が1つのファイルを参照している場合がある)。 ハッシュを作成し、キーとしてファイルのデバイス番号とiノード番…

9.3 ファイルをコピー、もしくは移動する

標準モジュールFile::Copyを使用する use File::Copy; copy($oldfile, $newfile); move($oldfile, $newfile);

9.2 ファイルを削除する

組み込み関数unlinkを使用する unlink($FILENAME) or die; unlink(@FILENAMES) == @FILENAMES or die;

9.1 タイムスタンプを取得、設定する

ファイルの最終更新時刻(書き込み、変更が行われた時刻)、最終アクセス時刻(読み込みが行われた時刻)を取得して変更したい。 stat関数で情報を取得し、utime関数で設定を行う。 ($READTIME, $WRITETIME) = (stat($filename))[8,9]; utime($NEWREADTIME, $NEW…

8.23 文字列をファイルとして扱う

文字列形式のデータをファイルとして扱いたい。例えば、引数としてファイルハンドルを受け取るサブルーチンに、直接文字列を渡して処理させたい。 open($fh, "+<", \$string); # $stringの中身の読み書きが可能

8.22 2つのファイルの内容を比較する

File::Compareモジュールを使用する use File::Compare; if (compare($FILENAME_1, $FILENAME_2) == 0) { # 2つのファイルが等しい場合 } if (compare(*FH1, *FH2) == 0) { # 2つのファイルが等しい場合 } if (compare($fh1, $fh2) == 0) { # 2つのファイル…

8.21 MicrosoftのテキストファイルをUnicodeに変換する

エンコーディングレイヤを適切に設定して、読み込んだテキストファイルをUnicodeに変換する。 binmode(IFH, ":encoding(cp1252)") || die;

8.20 ファイルハンドルに対して、Unicodeを読み書きする

入出力レイヤを使用して、特定のファイルハンドルからデータを読み込む場合、もしくは、特定のファイルハンドルにデータを書き込む場合には、特定のエンコーディングを使用するようにPerlに指示する。 open(my $ifh, "<:encoding(ENCODING_NAME)", $filename); open(my $ofh, ">:encoding(ENCODING_NAME)", $filename);</:encoding(encoding_name)",>

8.19 デフォルトの入出力例レイヤを設定する

openプラグマを使用する。 use open IO => ":raw:utf8";

8.18 ファイルを配列として扱う

ファイルは行のリスト、レコードのリストと見なすことができる。そこで、ファイルへのアクセス、ファイルを操作を、Perlの協力な配列操作を介して行えるようにしたい。 Tie::Fileモジュールを使用する use Tie::File; use Fcntl; tile @data, Tie::File, $FI…

8.17 ファイルの信頼性をテストする

ファイルの設定情報を読み込みたい。そして、そのファイルの所有者以外のユーザの書き込み権限(および読み取り権限)が無効になっていることを確認したい。 stat関数を使用して、ファイルの所有者、パーミッション情報を取得する ( $dev, $ino, $mode, $nlink…

8.16 設定ファイルを読み込む

VAR(変数)=VALUE(値)と言う単純な設定ファイルを用意し、下記のコードで処理する。 while (<CONFIG>) { chomp; s/#.*//; s/^\s+//; s/\s+$//; next unless length; my ($var, $value) = split(/\s*=\s*/, $_, 2); $User_Preferences{$var} = $value; } 設定ファイル</config>…

8.15 固定長レコードを読み込む

read関数とunpack関数を使用する # $RECORDSIZEはレコード長(単位はバイト) # $TEMPLATEはレコードをunpackするときの使用するテンプレート # FILEは読み込み対象のファイル # @FIELDSは各フィールドを格納する配列(1つの要素に1つのフィールドが格納される)…

8.14 バイナリファイルから文字列を読み込む

特定のアドレスにあるNULで終わる文字列を読み込みたい バイナリモードに切り替え、$/にASCIIのNULを設定してから、<>を使用して文字列を読み込む。 binmode(FH); # バイナリモード $old_rs = $/; # $/の元の値を保存 $/ = "\0"; # ASCIIのNUL seek(FH, $add…

8.13 ランダムアクセスファイルを更新する

バイナリファイルからレコードを読み込み、その値を変更して書き戻したい。 最初にレコードをreadして、対象の値を更新する。その更新した値をpackして、前のアドレスにseekして書き戻す。 use Fcntl; # SEEK_SET定数とSEEK_CUR定数を使用するため $ADDRESS …

8.12 バイナリファイルにランダムにアクセスする

大きなファイルの中間位置にあるバイナリレコードを読み込みたい。 最初にレコードのサイズを取得する。それにレコード番号を乗じて、バイトアドレスを取得する。最後にseekでバイトアドレスに移動し、readでレコードを読み込む。 $ADDRESS = $RECSIZE * $RE…

8.11 バイナリファイルを処理する

binmode関数を使用する。引数にはファイルハンドルを指定する。 binmode(HANDLE);

8.10 ファイルの最後の行を削除する

Tie::FIleモジュールを使用して、ファイルを配列にtieする。 use Tie::File; tie @lines, Tie::File, $file or die; delete $lines[-1];

8.9 可変長テキストフィールドを処理する

splitとフィールドセパレータにマッチするパターンを使用 # PATTERNで区切られている$RECORD内の各フィールドを抽出 @FIELDS = split(/PATTERN/, $RECORD);

8.8 ファイル内の特定の行を読み込む

所要の行に到達するまで行を読み込む # 行番号$DESIRED_LINE_NUMBERの行を探索する $. = 0; do { $line = <HANDLE> } until $. == $DESIRED_LINE_NUMBER || eof; ファイル内の各行を配列に格納する @lines = <HANDLE>; $LINE = $lines[$DESIRED_LINE_NUMBER]; Tie::Fileモジ</handle></handle>…

8.7 全ての行をランダムに並べ替える

全ての行を配列に読み込んで、List::Utilモジュールのshuffle関数を使用してシャッフルする。 use List::Util qw(shuffle); while (<INPUT>) { push(@lines, $_); } @reordered = shuffle(@lines); foreach (@reordered) { print OUTPUT $_; }

8.6 ファイルからランダムに行を取り出す

randと$.(現在の行番号)を使用して、どの行を取り出すか決める。 srand; rand($.) < 1 && ($line = $_) while <>; # $lineにランダムに取り出された行が格納される。

8.5 ファイルに継続的に追加されるデータを読み込む

ファイルに継続的に追加されるデータを読み込みたい。しかし、ファイルのその時点でのEOFに到達すると、読み込みエラーが発生してしまう。 EOFまで読み込み、スリープし、EOFフラグをクリアして読み込みを行う。 for (;;) { while (<FH>) { .... } sleep $SOMETI</fh>…