ファイルの内容を置き換える必要がある

ファイルの内容を置き換える必要がある

ついています。内容を含むscript.txtファイルがあります。

$cat script.txt

SET TABLESPACE CONTAINERS FOR 3
-- IGNORE ROLLFORWARD CONTAINER OPERATIONS
USING (
FILE '/db2data2/dbs/rahtest/rahtest1.lrg'  5120
);


SET TABLESPACE CONTAINERS FOR 4
-- IGNORE ROLLFORWARD CONTAINER OPERATIONS
USING (
  FILE   '/db2data2/dbs/rahtest/rahtest2.lrg'  5120
);

私の要件は行のファイルシステムです

FILE '/db2data2/dbs/rahtest/rahtest1.lrg' 5120
FILE   '/db2data1/dbs/rahtest/rahtest2.lrg'  5120

交換する必要があります

/db2data2/dbs/rahtest/rahtest1.lrg

そして

/db2data2/dbs/rahtest/rahtest2.lrg

他のファイルシステムと

/db2data3/dbs/rahtest/rahtest1.lrg

そして

/db2data3/dbs/rahtest/rahtest2.lrg

それぞれ。

他の部分は同じでなければなりません。私の出力は次のようになります -

FILE '/db2data3/dbs/rahtest/rahtest1.lrg'  5120
FILE '/db2data3/dbs/rahtest/rahtest2.lrg'  5120

私のファイルに反映する必要があります。線の中に線がどこにあるのかわかりません。 sedを使ってみました。この行を変数var1とvar2に入れようとしました。

var1=`echo /db2data2/dbs/rahtest/rahtest1.lrg'
var2=`echo /db2data2/dbs/rahtest/rahtest2.lrg'
var3=`echo /db2data3/dbs/rahtest/rahtest1.lrg'
var4=`echo /db2data3/dbs/rahtest/rahtest2.lrg'

私がしようとしているとき

sed 's/$var/$var3' script.txt

/があるので失敗します。私はAIXを使用しています。私の最終ファイルは次のようになります -

SET TABLESPACE CONTAINERS FOR 3
-- IGNORE ROLLFORWARD CONTAINER OPERATIONS
USING (
FILE '/db2data3/dbs/rahtest/rahtest1.lrg'  5120
);


SET TABLESPACE CONTAINERS FOR 4
-- IGNORE ROLLFORWARD CONTAINER OPERATIONS
USING (
  FILE   '/db2data3/dbs/rahtest/rahtest2.lrg'  5120
);

答え1

テキストにaがある場合は、sedパラメータの区切り文字として/aなどの他の文字を使用できます。また、変数を使用すると、単一引用符内に変数は拡張されないため、コマンドに二重引用符()を使用する必要が|あります。この試み:""sed

var1='/db2data2/dbs/rahtest/rahtest1.lrg'
var2='/db2data2/dbs/rahtest/rahtest2.lrg'
var3='/db2data3/dbs/rahtest/rahtest1.lrg'
var4='/db2data3/dbs/rahtest/rahtest2.lrg'

sed -e "s|$var1|$var3|g" -e "s|$var2|$var4|" script.txt

答え2

正規表現の変数情報を強力に処理するには、正規表現メタ文字をエスケープする必要があります。この質問は何度も答えられ、私自身も何度も答えてみましたが、とにかく結論は次のとおりです。

^$*[]\.

^基本正規表現のメタ文字です。これらのそれぞれは、以下のように正規表現で特別な意味を持ちます。通事論そして文字通り解釈されません。これらのいくつかの重要性は実際には場所によって異なります。可能適切なエスケープなしで正規表現で囲むことは意味しません。しなければならない- 特に正規表現が検証されていない入力で構成されている場合。

しかし、もっとたくさんあります:

delimiter newline &

sed s///^代替構文文字です。区切り文字は伝統的に変更可能で、自動的に新しいコマンドの最初の文字/として解釈されます。seds

改行 - 左正規表現声明の側面は実際には避けられない。そこには妥当性はありません。改行文字を変更する唯一の方法は、\nエスケープ文字を使用することです。しかし、唯一の方法は得る正規表現で見つかったパターン空間の改行は、ユーザーが直接入力した改行である可能性があるため、通常これは問題ではありません。交換右s///-変えるside - 改行文字は他のすべてと同様にエスケープ可能です。\これはエスケープメタ文字です。についても同様です&

したがって、強力なsed変数スクリプトを作成するには、エスケープする必要があります。これが唯一の方法です。ドアに区切り文字があると予想して区切り文字を変更することは、信頼できるアプローチではありません。入力を検証し、構文エラーの可能性を排除するか、構文文字をエスケープして目的の意味を示します。強力なプログラムを書くには2つの方法があります。他の方法はありません。

幸いなことに、sedこれは仕事がとても簡単になりました。前述のように、\バックスラッシュはエスケープメタ文字であり、2倍になるとそれ自体がエスケープされます。だから我々はsedそれを脱出するために使用することができますsed

printf %s\\n "$regex_field" "$replace_field" |
sed -ne'h;n' -e's|[\&/]|\\&|g'               \
    -ex      -e's|[]/\.$^*[]|\\&|g'          \
    -eG      -e's|\(.*\)\n\(.*\)|s/\1/\2/|p' |
sed -f-      edit_file

願いより?入力は改行で区切られます。したがって、作成されたように改行は許可されません。$regex_field または $replace_field。あなたできるこれを処理することも可能ですが、そうではないので、入力期待を検証してそれを除外します。

いずれの場合も、入力行は最初の行とペアになりsed、aの右側に関連する文字をエスケープすると、各行のペアの前半のhコピーが保存され、2行目にジャンプされます。代替文。次に、予約済みスペースとパターンスペースを変更し、左からエスケープしてから、行行区切り文字で区切られたRHSをLHSに追加します。最後に行うことは、エスケープされたコマンドを標準出力に印刷する前にこれらのビットを追加することです。nsed s///xG\ns///p

2番目はsedスクリプトファイルを読み込みます。- /dev/fd/0(通常は標準入力として解釈されますが、そうでない場合は試してみることもできます)次に、名前付きスクリプトを適用します。edit_file

関連情報