2016-12-14 8 views
0

私が行う必要があるのは、sedコマンドを使ってperlからファイルの行を置き換えることです。問題は、ファイルに入れる必要がある行がいくつかの場所にあり、私はperl/sedを削除せずに\をkeppする方法を理解していません。sedを使用してテキストファイル内の行を置き換えますが、をperlスクリプトの置換行の一部として残してください。

例は次のとおりです。私は、ファイルに取得する必要があり

destination=Manager {manager hostname=Bill,Manager port=8443} Fred 

::私は取得ファイルで

system sed "s/^destinaion=.*/destination=Manager {manager hostname\=$NAME,Manager port\=8443} $USER_NAME/" -i /usr/local/example_file.txt; 

destination=Manager {manager hostname\=Bill,Manager port\=8443} Fred 

これは、設定のプロパティファイルであり、それは正確である必要があります。

Perlで私のコマンド(単なる例):

$VAR1=$NAME 

$VAR2=$USER_NAME 

$VAR3='destination=Manager {manager hostname\\\\' 

$VAR4='Manager port\\\\=8443} ' 

system sed 's/^destinaion=.*/$VAR3=$VAR1,$VAR4 $VAR2/' -i 
/usr/local/example_file.txt; 

出力した:

destination=Manager {manager hostname\=Bill,Manager port\=8443} Fred 

私は私のために動作し、次の解決策を考え出したこのサイトを使用して

これは、問題の解答とredhatバージョンに応じて同じ行を4つの異なるプロパティファイルに渡しているので、うまくいきました。私がインストールしようとしているソフトウェアには、どのRedHatバージョンが使用されているかに応じて異なるプロパティファイルがあります。私は1つのインストールを行うことによってプロパティファイルを作成しなければならないし、スクリプト内のプロパティファイルを変更して、スクリプトを実行してエラーを監視できるようにforeachを使ってすべてのサーバーにインストールを行う。

私は現在2つのバージョンを使用していますので、正しいプロパティファイルを選択するためにスクリプトにif文を追加する必要がありました。

+0

難しいです。いくつのプロセスが文字列を解釈し、バックスラッシュを取り除いているのか調べなければなりません。 1つのバックスラッシュを出力に入れるには、 'sed'は' s/.../.../'操作の置換部分に2つの連続するバックスラッシュを表示する必要があります。それを二重引用符で囲むので、Perlはバックスラッシュも解釈することができます。これは、出力にPerlでそれぞれ4つのバックスラッシュが必要であることを意味します。 –

+4

通常、置換をPerl自体で行うのは、シェルターを使わずに行う方が速いです。 – choroba

+1

より高速であるだけでなく、より重要なことに、エラーが発生しにくい。実際には、複雑で十分にテストされた 'sed'スクリプトが用意されていない限り、なぜ' 'sed''を' 'perl''から呼びたいのか、私は困惑しています。 – reinierpost

答えて

0

コメントで述べたように:

それはトリッキーです。いくつのプロセスが文字列を解釈し、バックスラッシュを取り除いているのか調べなければなりません。出力に単一のバックスラッシュを入れるには、s/…/…/操作の置換部分に2つの連続するバックスラッシュを表示する必要があります。二重引用符で囲むので、Perlはバックスラッシュも解釈する機会を得ます。これは、出力にPerlでそれぞれ4つのバックスラッシュが必要であることを意味します。

あなたはsystemコールのための「配列」の表記を(構文を除いて間違っている - あなたはプレーンな言葉の周りのアイテム、および引用符の間にカンマが必要)を使用しているので、あなたはシェルが、文字列を解釈するのを避けますあまりにも。

これはmacOS Sierra 10.12で動作します。2、あまりにも(dataにファイルをリネーム)GNU sedで動作します:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $NAME = "Alexander"; 
my $USER_NAME = "The Great"; 
system "sed", "-e", "s/^destinaion=.*/destination=Manager {manager hostname\\\\=$NAME,Manager port\\\\=8443} $USER_NAME/", "-i.bak", "data"; 

ファイルdata前:

##destinaion=Manager {manager hostname=Bill,Manager port=8443} Fred 
destinaion=Manager {manager hostname=Bill,Manager port=8443} Fred 

ファイルdataをした後:

##destinaion=Manager {manager hostname=Bill,Manager port=8443} Fred 
destination=Manager {manager hostname\=Alexander,Manager port\=8443} The Great 

ここでバリアントスクリプトはそれです異なる数のバックスラッシュがどのように必要であるかを示しています。行内に8つのバックスラッシュがある例では、Perlは数字を4に半分にし、シェルは2に半分にし、sedは出力を意味する2として解釈します。 8つのバックスラッシュが連続して表示されているときは、可能な限り最善の方法で何かを処理していないと確信できます。 (昔の時代に、時にはtroffファイルは、行の16個のバックスラッシュを持っているでしょうが、彼らが必要であったときではないことが多い、と非常に少数の人々は、なぜ理解していた。)ここで

#!/usr/bin/perl 

use strict; 
use warnings; 

my $NAME = "Alexander"; 
my $USER_NAME = "The Great"; 
system "sed", "-e", "s/^D1=.*/destination1=Manager {manager hostname\\\\=$NAME,Manager port\\\\=8443} $USER_NAME/", "-i.bak", "data"; 
system "sed -e \"s/^D2=.*/destination2=Manager {manager hostname\\\\\\\\=$NAME,Manager port\\\\\\\\=8443} $USER_NAME/\" -i.bak data"; 
system "sed -e 's/^D3=.*/destination3=Manager {manager hostname\\\\=$NAME,Manager port\\\\=8443} $USER_NAME/' -i.bak data"; 

が初期バリアントデータファイルです:

をあなたは $NAMEとを必要としなかった場合は

destination1=Manager {manager hostname\=Alexander,Manager port\=8443} The Great 
destination2=Manager {manager hostname\=Alexander,Manager port\=8443} The Great 
destination3=Manager {manager hostname\=Alexander,Manager port\=8443} The Great 

D1=Manager {manager hostname=Bill,Manager port=8443} Fred 
D2=Manager {manager hostname=Bill,Manager port=8443} Fred 
D3=Manager {manager hostname=Bill,Manager port=8443} Fred 

はここでバリアントデータファイルにバリアントスクリプトを実行した結果ですが展開されている場合は、配列表記のs/…/…/コマンドの前後に一重引用符で囲まれた別のバリアントが存在する可能性があります。 4つではなく、2つのバックスラッシュが必要になります。

関連する問題