web-dev-qa-db-ja.com

sed:行の一部を置き換える

行の一部をsedに置き換えるにはどうすればよいですか?

この線

DBSERVERNAME     xxx

次のものに置き換える必要があります。

DBSERVERNAME     yyy

値xxxは異なる場合があり、dbservernameと値の間に2つのタブがあります。この名前と値のペアは、構成ファイルの多くの1つです。

私は次の後方参照で試しました:

echo "DBSERVERNAME    xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'

そして、それはエラーを引き起こしました: `s 'コマンドのRHSの無効な参照\ 1。

式の何が問題になっていますか? GNU sed。

38
calvinkrishy

これは動作します:

sed -rne 's/(dbservername)\s+\w+/\1 yyy/gip'

(-rオプションを使用すると、括弧をエスケープする必要はありません。)

説明のビット:

  • -rは拡張正規表現です-正規表現の記述方法に違いが生じます。
  • -nは指定されない限り印刷されません-sedはデフォルトで印刷されます。
  • -eは、それに続くものが式であることを意味します。式を分解してみましょう:
    • s///はsearch-replaceのコマンドです。最初のペアの間にあるのは一致する正規表現で、2番目のペアは置換です。
    • gip、これは検索置換コマンドに続きます。 gはグローバルを意味します。つまり、最初のマッチではなくすべてのマッチが1行で置き換えられます。 iは大文字と小文字を区別しません。 pは、完了時に印刷することを意味します(-n以前のフラグ!)、
    • 括弧は、後で表示される一致部分を表します。したがって、dbservernameは最初の一致部分です。
    • \sは空白、+は1つ以上(vs *、0個以上)の出現、
    • \wは単語、つまり任意の文字、数字、またはアンダースコアです。
    • \1は、GNU sedの特別な表現であり、付随する検索で最初に括弧で囲まれた一致を出力します。
47
Jeremy Stein

他の人はすでに括弧のエスケープについて言及していますが、行の最初の部分が一定の場合、なぜ後方参照が必要なのですか?

簡単にできます

sed -e 's/dbservername.*$/dbservername yyy/g'
9
Vicky

(および)をエスケープしています。私はあなたがそれをする必要はないと確信しています。試してください:

 sed -rne 's /(dbservername)[[:blank:]] + \([[:alpha:]] + \)/\1 yyy/gip' 
2
apandit

単一引用符を使用する場合、物事をエスケープしないでください。すなわち。

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip'
1

両親を逃げてはいけません。試してください:

echo "DBSERVERNAME    xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip'
1
Pesto

これはあなたのために働くかもしれません:

echo "DBSERVERNAME     xxx" | sed 's/\S*$/yyy/'
DBSERVERNAME     yyy
1
potong

これを試して

sed -re 's/DBSERVERNAME[ \t]*([^\S]+)/\yyy/ig' temp.txt

またはこれ

awk '{if($1=="DBSERVERNAME") $2 ="YYY"} {print $0;}' temp.txt

0
Mirage