1

「.backup.conf」という名前の構成ファイルを変更するシェルスクリプトで問題が発生しています。

構成ファイルは次のようになります。

inputdirs=(/etc /etc/apm /usr/local)
outputdir="test_outputdir"
backupmethod="test_outputmethod"
loglocation="test_loglocation"`

私のスクリプトは構成ファイル変数の1つを変更する必要があり、最後の3つの変数に問題はありませんでした。

変数"inputdirs"/etc/を/etc/ perlに変更したい場合、どの式を使用すればよいですか?

エコーを追加で使用すると、ファイルの最後にのみ追加されます。

次の形式でsedを使用してみました。 sed -i 's/${inputdirs[$((izbor-1))]}/$novi/g' .backup.confここで、「izbor」はinputdirsから変更する変数であり、「novi」は新しいパス(/ etc / perlなど)です。

したがって、次の構成ファイルを使用し、変数を使用すると、最初の変数をに変更する必要が$izbor=1あり 、変数inputdirsは最終的に次のようになります。$novi=/etc/perlinputdirs=/etc/etc/perlinputdirs=(/etc/perl /etc/apm /usr/local)

ご協力ありがとうございました!

4

2 に答える 2

2

あなたはこれを試すことができます:

enovi="$(printf '%s\n' "$novi" | sed -e 's/[\\&/]/\\&/g')"
izbor1="$(expr "$izbor" - 1)"
sed -rie "s/([(]([^ ]* ){$izbor1})[^ )]*/\\1$enovi/" config.txt

コマンドの要約:

  1. $enovi最初の行は、エスケープされた内容を持つ変数を生成します$novi。基本的に、次の文字はエスケープされます:&、、、。だからになります。\//etc/perl\/etc\/perl
  2. 新しい変数デクリメントを作成します$izbor
  3. これが実際の代替式です。部分的に説明します:
    1. まず、括弧文字と一致させます[(]
    2. 次に、スペース()が後に続く非スペースのシーケンスを検索します[^ ]*
    3. この検索(内側の括弧内のグループ化によって識別されます)は、何$izbor1度も繰り返されます({$izbor1}
    4. 前の式は、補助変数にキャプチャされるように、外側の括弧グループにグループ化されます\1
    5. これで、置き換えたい単語と一致します。スペースではなく、閉じ括弧ではない一連の文字で構成されます(これは最後の単語の場合を処理するためです)
    6. 置換は、キャプチャされた値\1とそれに続く新しい文字列によって形成されます。

これがお役に立てば幸いです=)

于 2012-10-19T17:32:14.513 に答える
1

$ izborをインデックスとして使用しようとしている場合は、おそらく。のフラグになりs///ます。入力が(空白なしで)一致すると仮定すると、^inputdirs=(おそらく次のように回避できます。

sed -i '/^inputdirs=(/{ 
    s/(/(  /; s/)/ )/;   # Insert spaces inside parentheses
    s@ [^ ][^ ]* @ '"$novi@$izbor"'; 
    s/( /(/; s/ )/)/; }  # Remove inserted spaces
' .backup.conf

最初の2つの式は、括弧内に空白があることを確認するため、入力にすでに空白がある場合は必要ない場合があります。上記では少しわかりにくいですが、基本的に、実行している置換は次のようになります。

s@ [^ ][^ ]* @/etc/perl@2

ここで、2フラグはsedに2回目の一致のみを置き換えるように指示します。これは本当に壊れやすいです。なぜなら、前inputdirsに空白がなく、親の中に空白がなく、タブを処理しないからですが、うまくいくはずです。また、より単純にとして記述sedできるものもありますが、それは普遍的ではありません。[^ ][^ ]*[^ ]+

于 2012-10-19T17:46:45.893 に答える