2009-06-02 11 views
1

ファイルの検索と置換を行う正規表現を作成しようとしています。以下はスクリプトです。検索と編集のための正規表現の構築

#!use/bin/perl 
use strict; 
use warnings; 
my $line = $ARGV[0]; 
my $find = "[^a-zA-Z0-9]+seqfile[^a-zA-Z0-9]+=[^a-zA-Z0-9]+[a-z]+.."; 
my $replace = "done"; open (FILE, ">>/home/user/Desktop/test") || die "cant open file \n"; 
my @body = <FILE>; 
foreach $line (@body) { 
if (my $line =~ s/$find/$replace/g){ 
print FILE $line; 
} 
else { 
print "did not replace \n\n"; 
} 
} 
close(FILE); 
print "reached here\n"; 
exit; 

プログラムをテストするために実行しているサンプルテストファイルは、数行のテキストで構成されています。置換したい文字列は、最初の行に"tobereplaced = file.aa"となります。スペース "\ s"の正規表現は私のシステムでは受け入れられなかったので、私はcarot(^)をアルファベット/数字以外の文字に使用しなければなりませんでした。私はプログラムが実行されたことを知っています。私のプログラムは、私が指定 正規表現を使用して文字列の 検索することができませんなぜ誰もが

  1. を提案することができます。私のシステムは 「\ s」を認識し、誰もが正規表現を研究するためのいくつかの の良いソースを示唆することができ、エラーも
  2. そして、「認識できないが、\は テストで通過sのエスケープ 」与えるものではありませんなぜ
  3. 。あなたは、二重引用符で囲まれた文字列を使用しているため

おかげ

+0

オンライナーがほしい場合は、http://stackoverflow.com/questions/934733/perl-loop-through-a-file-and-substitute/934756#934756を参照してください。 –

+0

「[^ a-zA -Z0-9] "は" \ P {IsAlnum} " – Axeman

答えて

3

\sは受け付けていません。二重引用符で囲まれた文字列は\sの意味を理解しようとしているし、それをどうするかわからない、あなたはそれを動作させるために、次のもののいずれかを言うことができます。

  • "\\s+seqfile\\s+=\\s+[a-z]+.."
  • '\s+seqfile\s+=\s+[a-z]+..'
  • qr/\s+seqfile\s+=\s+[a-z]+../

通常の文字列よりも高速なコンパイル済みの正規表現を作成するため、最後の形式が推奨されます。あなたは

print "$find\n"; 

を言うとバック(?-xism:\s+seqfile\s+=\s+[a-z]+..)を得ることができるので、正規表現を期待していない状況でそれを使用する場合にコンパイル正規表現は、文字列化します。また

、あなたは文字クラス内にキャレットを置く必要があります文字クラスを否定しようとしている場合:[^a-zA-Z0-9]は(少なくともASCII用)英数字でない意味しますが、^[a-zA-Z0-9]は、文字列の先頭に英数字にマッチ意味(または/mオプションが設定されている場合は、行の先頭)。

また、>>モードでファイルを開くと、そのファイルを読むことができません。 STDIN(またはコマンドラインのファイル)から読み込み、STDOUTに書き込むようにコードを変更しました。これはフィルタリングと呼ばれる標準的なPerl技術です。プログラムのパイプラインを構築することができます。

perl -pe 's/\s+seqfile\s+=\s+[a-z]+../done/g' inputfile 
:あなたはこの

./script.pl inputfile > outputfile 

またはここでは、この

cat inputfile | ./script.pl > outputfile 

はスクリプト

#!use/bin/perl 

use strict; 
use warnings; 

my $find = qr{ \s+ seqfile \s+ = \s+ [a-z]+ .. }x; 
my $replace = "done"; 

while (<>) { 
    s/$find/$replace/g; 
    print; 
} 

はまた、ワンライナーに煮詰めすることができているようなスクリプトを実行することができます

リージョを学習するための優れた情報源XESは次のようになります。

+0

私が言及したように、私がスクリプトで\ sを使うときはいつでも、「認識できないエスケープがファイルを通過しました」というエラーが表示されます。だから私はそれがrecogizedされていないと思いますか? – shubster

+1

これは、正規表現引用符のような演算子(http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators)ではなく、二重引用符で囲まれた文字列を使用しているためです。本当にqr //の代わりに文字列を使用したい場合は、\\ sと言うことができますが、qr //は多くの理由により優れています。 –

+0

ファイル($ FILE、 '> testfile')を上書きしたい場合は、正確に6桁後に単語etcを検索すると、次の正規表現は使えますか?$ find = '{\ s、6} seqfile \ s = snew1.aa 'を置き換え、$ replace =' {\ s、6} seqfile \ s = \ snew2.aa 'に置き換えてください。 – shubster

0

あなたは追加モードでファイルを開いた後、読み取りと書き込みの両方のために試してみましたそれ。ファイルの読み書きは可能ですが、別のモードを使用する必要があります。しかし、正確に同じ数の文字を置き換えたくない場合は、1つのファイルから読み込み、すべての部分(変更された部分と変更されていない部分)を別のファイルに書き出す必要があります。

関連する問題