2010-12-08 48 views
25

ファイルの内容を変更、削除、挿入するか、ファイルの先頭に追加することで、ファイルの内容を変更したいと考えています。 Perlでどうすればいいですか?Perlでは、ファイルの行を変更、削除、挿入、またはファイルの先頭に追加するにはどうすればよいですか?


これはofficial FAQからquestionです。我々はimporting the perlfaq to Stack Overflowです。

+0

[どのように私は、変更、削除、またはファイル内の行を挿入、またはPerlでファイルの先頭に追加しますか?](http://stackoverflow.com/questions/2322140/の可能重複ファイルの先頭行に追加するか、または行頭に追加するかを指定する) –

答えて

41

(これはofficial perlfaq answerで、マイナス後続の編集)

、挿入、変更、またはテキストファイル から行を削除する基本的な考え方は、あなたがしたいポイントにファイルを読み込み、印刷関係 を変更して変更を加え、残りのファイルを読み取り、印刷します。 Tie::Fileなどのモジュールでは、偽装することができますが、Perlは回線にランダムアクセスを提供しません(特に、 入力区切り文字、$/が変更可能です)。あなたが挿入するために必要な部品を追加し、その基本的なフォーム内の

open my $in, '<', $file  or die "Can't read old file: $!"; 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

while(<$in>) 
    { 
    print $out $_; 
    } 

close $out; 

:これらのタスクを実行する

A Perlプログラムは、ファイルを閉じて、その行を印刷し、 をファイルを開くの基本的な形をとります、変更、または 行を削除します。

行を先頭に追加するには、既存の行を印刷する ループを入力する前にそれらの行を印刷します。

open my $in, '<', $file  or die "Can't read old file: $!"; 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC 

while(<$in>) 
    { 
    print $out $_; 
    } 

close $out; 

既存の行を変更するには、 whileループ内の行を変更するコードを挿入します。この場合、コードは小文字の "perl"のバージョンをすべて見つけて、大文字小文字を区別します。すべての行で起こるので、すべての行でそれを行うことになっているのは、 であることを確認してください!

open my $in, '<', $file  or die "Can't read old file: $!"; 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

print $out "# Add this line to the top\n"; 

while(<$in>) 
    { 
    s/\b(perl)\b/Perl/g; 
    print $out $_; 
    } 

close $out; 

特定の行のみを変更するには、入力行番号$。が便利です。 最初に変更したい行を読み込んで印刷します。次に、変更する単一行を と読んで変更して印刷します。その後、 は、行の残りの部分を読んで、それらを印刷:

while(<$in>) # print the lines before the change 
    { 
    print $out $_; 
    last if $. == 4; # line number before change 
    } 

my $line = <$in>; 
$line =~ s/\b(perl)\b/Perl/g; 
print $out $line; 

while(<$in>) # print the rest of the lines 
    { 
    print $out $_; 
    } 

を行をスキップするには、ループのコントロールを使用します。次の例では、 __END__または__DATA__のいずれかが検出されると、最後にすべての処理が停止します( のコメント行はスキップされます)。

while(<$in>) 
    { 
    next if /^\s+#/;    # skip comment lines 
    last if /^__(END|DATA)__$/; # stop at end of code marker 
    print $out $_; 
    } 

あなたが出力に表示したくない 行をスキップするために、次を使用して、特定の行を削除するものと同じ種類のを行います。限り(

while(<$in>) 
    { 
    next unless $. % 5; 
    print $out $_; 
    } 

いくつかの奇妙な理由で、あなたが本当にむしろライン・バイ・ラインを処理するよりも、一度 をファイル全体を見たい、場合は、あなたがそれを読まことができます。この例では、すべての 5行をスキップしますあなたができるように メモリにすべてのものを合わせてください!):このようFile::SlurpTie::Fileなど

open my $in, '<', $file  or die "Can't read old file: $!" 
open my $out, '>', "$file.new" or die "Can't write new file: $!"; 

my @lines = do { local $/; <$in> }; # slurp! 

    # do your magic here 

print $out @lines; 

モジュールは、あまりにもその を支援することができます。ただし、ファイル全体を一度に読み取ることはできません。 Perlは、プロセスが終了するまで、 のメモリをオペレーティングシステムに戻しません。

また、Perlの1ライナーを使用して、ファイルをインプレースで変更することもできます。次の は、inFile.txt内のすべての 'Fred'を 'Barney'に変更し、ファイルを 新しい内容で上書きします。 -pスイッチを使用すると、コード の周りにwhileループがラップされ、-eと指定し、-iはインプレース編集を有効にします。現在の 行は$_にあります。 -pを指定すると、Perlは自動的に$_という値を というループの最後に表示します。詳細はperlrunを参照してください。

perl -pi -e 's/Fred/Barney/' inFile.txt 

追加する-iaファイル拡張子を与え、inFile.txtのバックアップを作成するには:

perl -pi.bak -e 's/Fred/Barney/' inFile.txt 

を唯一の5行目を変更するには、あなたが$.をチェックするテストを追加することができ、入力 ラインテストが通過するとき数、そして唯一の操作を実行します。

perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt 

は、特定の行の前の行を追加するには、行を追加することができます前に(またはラインを!)枚のPerlのプリント$_

perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt 

は後に行を挿入するには:あなたも プリントループの最後に現在の行から、ファイルの先頭に行を追加することができます

perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt 

既にファイル内にあるものは、 -nスイッチを使用してください。 のようにちょうど -pのようになりますが、ループの最後に $_が表示されないので、 自分で行う必要があります。この場合、最初に $_を印刷し、追加する行を として印刷します。

perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt 

行を削除するには、必要な行だけを印刷します。

perl -ni -e 'print unless /d/' inFile.txt 

&hellip;または&hellip;

perl -pi -e 'next unless /d/' inFile.txt 
+0

/d/'inFile以外の 'perl -ni -e' .txt'はマッチする行を削除するために実際には機能しましたが、/ d/'inFile.txt'がそうしないと、 'perl -pi -e'の次の行は削除されませんでした。また、次の場合を除いて、「次へ」を変更しなかった。これはperl 5.10.0です。何が起きているのか? –

関連する問題