我有一个文本文件,其中有一行

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext

我需要将上面的整行替换为

This line is removed by the admin.

搜索关键字是text_to_be_replace

我需要为此写一个shell脚本。如何使用sed实现这一点?


当前回答

在我的makefile中,我使用这个:

@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md

PS:不要忘记-i实际上改变了文件中的文本…因此,如果你定义为“Revision”的模式将改变,你也将改变模式来替换。

示例输出:

abc项目由John Doe撰写 修改:1190

因此,如果你设置模式“Revision: 1190”,这显然与你将它们定义为“Revision:”不同……

其他回答

在我的makefile中,我使用这个:

@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md

PS:不要忘记-i实际上改变了文件中的文本…因此,如果你定义为“Revision”的模式将改变,你也将改变模式来替换。

示例输出:

abc项目由John Doe撰写 修改:1190

因此,如果你设置模式“Revision: 1190”,这显然与你将它们定义为“Revision:”不同……

这个公认的答案并不适合我,原因如下:

我的sed版本不喜欢使用0长度扩展的-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)
    # FIX: No space after the option i.
    sed -i.bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
    mv "${FILE}.bak" /tmp/
}

因此本例使用提出了修正问题的方法:

change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile

到目前为止提供的所有答案都假设您了解要替换的文本,这是有意义的,因为这是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/'

要做到这一点,不依赖任何GNUisms,如-i不带参数或c不带换行符:

sed '/TEXT_TO_BE_REPLACED/c\
This line is removed by the admin.
' infile > tmpfile && mv tmpfile infile

在这种(POSIX兼容的)命令形式中

c\
text

文本可以由一行或多行组成,应该成为替换的一部分的换行符必须转义:

c\
line1\
line2
s/x/y/

其中s/x/y/是一个新的sed命令后,模式空间已替换为两行

line1
line2

您可以使用change命令替换整行,并使用-i标志进行适当的更改。例如,使用GNU sed:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo