用Sedreplace整个包含一个string的行

我有一个文本文件,有一个特定的行类似

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext 

我需要用上面的整行代替

 This line is removed by the admin. 

search关键字是TEXT_TO_BE_REPLACED

我需要为此编写一个shell脚本。 我怎样才能达到这个使用sed

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

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

您需要在前后使用通配符( .* )来replace整行:

 sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./' 

接受的答案不适用于我有几个原因:

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

所以这里是我想到的解决scheme,我认为应该适用于大多数情况:

 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/ } 

所以解决这个问题的例子用法就是:

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

上面的答案:

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

如果replacestring/行不是variables,则可以正常工作。

问题是在Redhat 5上\c逃脱了$ 。 双\\也没有工作(至less在红帽5)。

通过打击和审判,我发现,如果你的replacestring/行只是一行, c之后的\是多余的。 所以我没有在c之后使用\ ,把一个variables作为一个单独的replace行,这是一种乐趣。

代码看起来像这样:

 sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo 

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

 bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90" bash-4.1$ bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed vim test4sed ' ' ' DB_HOSTNAME=good replaced with 122.334.567.90 ' 

它工作正常

到目前为止所提供的所有答案都假设你知道一些关于要被replace的文本是有意义的,因为这是OP所要求的。 我提供了一个答案,假设您对要replace的文本一无所知,并且文件中可能会有一个单独的行,其中有相同或相似的内容,您不想replace它们。 此外,我假设你知道要更换的行的行号。

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

 # 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/' 

和上面的一样

 sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./' 

我经常使用正则expression式从文件中提取数据,我只是用它来replace字面引号\"没有:-)

 cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed s/\"//g | cut -d, -f1 > list.txt 

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

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

PS: 不要忘记,-i实际上改变了文件中的文本…所以如果你定义为“修订”的模式将改变,你也将改变模式来取代。

示例输出:

由John Doe撰写的Abc-Project

修订版:1190

所以,如果你设置的模式“版本:1190”显然是不一样的,你定义为“修订:”只…

 cat find_replace | while read pattern replacement ; do sed -i "/${pattern}/c ${replacement}" file done 

find_replace文件包含2列,c1与模式匹配,c2与replace,sed循环replace每个包含variables1模式之一的行