2

私はしばしばsysctl.conf、などのファイルを変更する必要があり、sedを使用して既存の値を置き換えることに慣れています。

sedで置き換えられなかった場合に、新しいキーと値のペアをファイルに追加する方法はありますか?

たとえば、次の例を使用します。bashスクリプトを使用して構成ファイルを変更します

sed -c -i "s/\($TARGET_KEY *= *\).*/\1$REPLACEMENT_VALUE/" $CONFIG_FILE

わずかな変更を加えて同じsed式を使用するように$TARGET_KEY = $REPLACEMENT_VALUE新しい行を追加するにはどうすればよいですか?$CONFIG_FILE

また、関連するトピックについて、$CONFIG_FILE存在しなかった場合に強制的に作成するにはどうすればよいですか?

4

2 に答える 2

4

sed1回の呼び出しですべてを簡単に行うことはできません。それを2つのステップにするのがおそらく最も簡単です:

if grep -q "$TARGET_KEY *= " $CONFIG_FILE; then   
   sed -c -i "s/\($TARGET_KEY *= *\).*/\1$REPLACEMENT_VALUE/" $CONFIG_FILE
else
   echo "$TARGET_KEY = $REPLACEMENT_VALUE" >>$CONFIG_FILE
fi

ただし、上記をより堅牢にするためにおそらく行うべきことがいくつかあります。

  1. 正規表現は固定されていません。つまり、「PORT」を設定しようとすると、「SUPPORT」なども検索/変更されます。

  2. 構成ファイルにスペースだけでなくタブも含まれている可能性がある場合は一致しません

  3. 置換値にスラッシュが含まれている場合は失敗します。

  4. $CONFIG_FILEファイルパスにスペースやシェルメタ文字が含まれている場合は、常に、のようなパラメータ展開を引用する必要があります。

  5. この場合は安全ですが、リテラルの円記号が必要な場合に、二重引用符で囲まれた文字列で単一の円記号を使用すると混乱する可能性があります。シェルは、その後に続くものを特別なシーケンスとして認識しない場合、それらをそのままにしますが、それらを2倍にするとより明確になります。

  6. -cあなたのバージョンのsedはどうしますか?私のLinuxバージョンもMacバージョンもそのようなオプションをサポートしていません。

だから私はこのようにします(^I'sはリテラルタブ文字を表し、^A'sリテラルcontrol-A文字、たとえばコマンドラインで最初にcontrol-Vと入力して入力します):

if grep -q "^[ ^I]*$TARGET_KEY[ ^I]*=" "$CONFIG_FILE"; then
   sed -i -e "s^A^\\([ ^I]*$TARGET_KEY[ ^I]*=[ ^I]*\\).*$^A\\1$REPLACEMENT_VALUE^A" "$CONFIG_FILE"
else
   echo "$TARGET_KEY = $REPLACEMENT_VALUE" >> "$CONFIG_FILE"
fi
于 2012-11-19T16:13:19.980 に答える
0

以下の擬似コードを使用します。

if (grep -q key); then
    sed...
else
    echo key=value >> $CONFIG_FILE
fi
于 2012-11-19T15:50:45.700 に答える