Вопрос по – sed: заменить часть строки

34

Как можно заменить часть строки на sed?

Линия

DBSERVERNAME     xxx

следует заменить на:

DBSERVERNAME     yyy

Значение xxx может варьироваться, и между dbservername и значением есть две вкладки. Эта пара имя-значение является одной из многих из файла конфигурации.

Я попытался со следующей обратной ссылкой:

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

и это привело к ошибке: неверная ссылка \ 1 на `s & apos; команда RHS.

Что не так с выражением? Использование GNU sed.

Ваш Ответ

7   ответов
1

Вы не должны избегать вещей, когда используете одинарные кавычки. то есть.

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

Попробуй это

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

или это

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

42

Это работает:

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

(Когда вы используете опцию -r, вам не нужно выходить за пределы скобок.)

Немного объяснения:

  • -r is extended regular expressions - makes a difference to how the regex is written.
  • -n does not print unless specified - sed prints by default otherwise,
  • -e means what follows it is an expression. Let's break the expression down:
    • s/// is the command for search-replace, and what's between the first pair is the regex to match, and the second pair the replacement,
    • gip, which follows the search replace command; g means global, i.e., every match instead of just the first will be replaced in a line; i is case-insensitivity; p means print when done (remember the -n flag from earlier!),
    • The brackets represent a match part, which will come up later. So dbservername is the first match part,
    • \s is whitespace, + means one or more (vs *, zero or more) occurrences,
    • \w is a word, that is any letter, digit or underscore,
    • \1 is a special expression for GNU sed that prints the first bracketed match in the accompanying search.
Я знаю, что вы, ребята, имеете большой опыт работы с командами оболочки ... но, пожалуйста, позаботьтесь о начинающих linux noobs, где это возможно .... все внутри'' нужно объяснить .... или я должен пройти через всеdoc
1

Вы не должны избегать своих родителей. Пытаться:

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

Вы избегаете своего (и). Я уверен, что вам это не нужно. Пытаться:

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

Другие уже упоминали о закрытии скобок, но зачем вообще нужна обратная ссылка, если первая часть строки постоянна?

Вы могли бы просто сделать

sed -e 's/dbservername.*$/dbservername yyy/g'
Это получает мой голос, потому что это самое простое решение простой проблемы. Использование обратной ссылки избавит вас от опечатки двух копийdbservername, Здесь это очевидно, но когда я изменяю postgresql.conf в sed, мне трудно сразу увидеть, набрал ли яlisten_address или жеlisten_addresses (Postgresql.conf). Оба выглядят правдоподобно, но только один является правильным.
Хорошая точка зрения! Я только что узнал об использовании regexps + sed, и разум только что решил 'regexp & apos; увидев эту конкретную задачу, то как «jwz»; сказал "у меня было две проблемы" (хотя не напрямую из-за регулярных выражений) :) calvinkrishy
1

Это может работать для вас:

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

Похожие вопросы