用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模式之一的行