sed はストリームの最後の行を繰り返します。

sed はストリームの最後の行を繰り返します。

私のスクリプトにこれに似たコードがあります...

smbconffile="/etc/samba/smb.conf"
sed -i 's/.*[\[CMI\]]/\[CMI\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[LOCAL\]]/\[LOCAL\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[NATIONAL\]]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || "Failed"

これにより、samba conf(smb.conf) の共有名が CMI$、LOCAL$、NATIONAL$ に変更されます。

私が持っている問題は、2番目のsedコマンドの後にsedが "NATIONAL"を見つけましたが、 "NATIONAL $"の代わりに "LOCAL $"に名前を変更することです。コマンドに問題がある人はいますか?どんな助けでも大変感謝します。

ベストアンサー1

文字クラス(角かっこ内の文字のリスト)を角かっこリテラルで囲まれたsmb.conf共有名と混合します。また、コマンドの形式が正しくありません。echoシェルは、ゼロ以外の状態で終了せずにコマンドを呼び出そうとします。sedFailed

いくつかのアドバイス:

  1. 文字クラスの削除(外部括弧)
  2. 先行を削除すると、.*先行コメントなどが削除されます。
  3. sed複数の文を含む単一コマンドの実行
  4. エラー状態メッセージの修正


sed -i 's/\[CMI\]/\[CMI\$\]/;
        s/\[LOCAL\]/\[LOCAL\$\]/;
        s/\[NATIONAL\]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || echo "Failed"`

逆参照を使用すると、代替式で元のプレフィックス(「[CMI」など)を再入力する必要はありませんが、これにより式を読み取るのが難しくなります。

もう1つの提案は、読み取り可能なグループ化と逆参照(IMO)を持つPerlを使用することです。

perl -pi -e 's/(\[(?:CMI|LOCAL|NATIONAL))\]/$1\$]/g' $smbconffile \
    && echo "Success" || echo "Failed"


編集する:[明確にすると、外部括弧を持つ元の式の問題は、(最初​​の場合)、、、、CMの後にランダムI]順序でを含む文字列と同じ文字クラスを生成することです]

$ echo '[IMC]' | sed 's/[\[CMI\]]/[something_else]/'
[IM[something_else]

$ echo '[FOOM]' | sed 's/[\[CMI\]]/[something_else]/'
[FOO[something_else]

外部角かっこを削除すると文字クラスが削除されるため、式は指定された部分文字列と正確に一致します。

おすすめ記事