使用Sed替换包含字符串的整行

Rah*_*hul 296 string shell sed

我有一个文本文件,其中有一个特定的行

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext
Run Code Online (Sandbox Code Playgroud)

我需要替换上面的整行

This line is removed by the admin.
Run Code Online (Sandbox Code Playgroud)

搜索关键字是 TEXT_TO_BE_REPLACED

我需要为此编写一个shell脚本.我怎样才能实现这个目的sed

Tod*_*obs 451

您可以使用change命令替换整行,并使用-i标志进行就地更改.例如,使用GNU sed:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
Run Code Online (Sandbox Code Playgroud)

  • @MarcusDowning GNU sed确实*不*需要空间; 它最初发布时效果很好.如果您的特定sed需要空间,那么请务必注意哪个sed不兼容,并添加必要的调用作为注释.但是,请不要在接受的答案中更改工作代码. (24认同)
  • 当直接跟一个变量时,`c \`有一个问题:`... c\$ VAR ...`反斜杠将逃脱美元.在这种情况下,我(在Ubuntu 15.10上使用bash/sed)必须编写`... c \\ $ VAR ... (16认同)
  • 如何使用变量而不是文本"This ..."?如果我用$ variable替换它,它不会打印其内容而是打印变量名称. (7认同)
  • 在Mac上使用:`sed -i''/ TEXT_TO_BE_REPLACED / c \此行已被管理员删除。/ tmp / foo`; (当第一个参数为空时,它将编辑文件中的文件,否则创建备份) (4认同)
  • 请注意,在c \之前需要一个空格.我刚刚编辑过来添加这个. (3认同)
  • `sed -i'/ TEXT_TO_BE_REPLACED/c \'"$ var"/ tmp/foo` (2认同)

Tho*_*hor 140

您需要.*在更换整行之前和之后使用wildards():

sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'
Run Code Online (Sandbox Code Playgroud)

  • 这适用于Mac OS X Yosemite,除了我使用-i和-e标志如下:`sed -i -e"s /.*search_string.*/Replacement_line /'file_being_searched.txt` (8认同)
  • 仅供参考.为了使其成为现实,可以添加`-i`选项 (2认同)

ske*_*ell 19

由于以下几个原因,接受的答案对我不起作用:

  • 我的sed版本不喜欢-i零长度扩展
  • c\命令的语法很奇怪,我无法让它工作
  • 我没有意识到我的一些问题来自未转义的斜线

所以这是我提出的解决方案,我认为应该适用于大多数情况:

function escape_slashes {
    sed 's/\//\\\//g' 
}

function change_line {
    local OLD_LINE_PATTERN=$1; shift
    local NEW_LINE=$1; shift
    local FILE=$1

    local NEW=$(echo "${NEW_LINE}" | escape_slashes)
    sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
    mv "${FILE}.bak" /tmp/
}
Run Code Online (Sandbox Code Playgroud)

因此用于解决问题的示例用法:

change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile
Run Code Online (Sandbox Code Playgroud)


小智 15

上面的答案:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
Run Code Online (Sandbox Code Playgroud)

如果替换字符串/行不是变量,则工作正常.

问题是在Redhat 5 \之后c逃脱了$.双重\\也不起作用(至少在Redhat 5上).

通过点击和试用,我发现如果您的替换字符串/行只是一行,那么\之后c是多余的.所以我没有使用\之后c,使用变量作为单个替换线,这是喜悦.

代码看起来像:

sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo
Run Code Online (Sandbox Code Playgroud)

请注意使用双引号而不是单引号.


b_l*_*shi 7

到目前为止提供的所有答案都假设您对要替换的文本有所了解,这是有道理的,因为这就是 OP 所要求的。我提供的答案假定您对要替换的文本一无所知,并且文件中可能有单独的一行具有您不想替换的相同或相似的内容。此外,我假设您知道要替换的行的行号。

以下示例演示了按特定行号删除或更改文本:

# replace line 17 with some replacement text and make changes in file (-i switch)
# the "-i" switch indicates that we want to change the file. Leave it out if you'd
#   just like to see the potential changes output to the terminal window.
# "17s" indicates that we're searching line 17
# ".*" indicates that we want to change the text of the entire line
# "REPLACEMENT-TEXT" is the new text to put on that line
# "PATH-TO-FILE" tells us what file to operate on
sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE

# replace specific text on line 3
sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/'
Run Code Online (Sandbox Code Playgroud)