我需要在文本文件中进行一组替换 E.g而不是跟随关键字符串
#include "martini.itp"
3个其他字符串,其中包含指向itp文件的准确路径
#include "../dir1/dir2/martini1.itp"
#include "../dir1/dir2/martini2.itp"
#include "../dir1/dir2/martini3.itp"
我试图使用下面的模式来实现它,我想这会产生错误,因为像./这样的字符应该使用指定的语法与sed语句隔离。
sed -i 's/#include "martini.itp"/#include "../dir1/dir2/martini_v2.0_lipids_all_201506.itp"\n#include "../dir1/dir2/martini_v2.0_ions.itp"\n#include "../dir1/dir2/martini_v2.0_solvents.itp"/' topol.top
答案 0 :(得分:3)
如果你正在使用固定字符串,你可以使用awk并避免任何转义(除了一些双引号):
awk '$0 == "#include \"martini.itp\"" {
$0 = "#include \"../dir1/dir2/martini1.itp\"" ORS \
"#include \"../dir1/dir2/martini2.itp\"" ORS \
"#include \"../dir1/dir2/martini3.itp\""
}
{ print }' file > tmp && mv tmp file
如果该行匹配,请将其替换为其他行。一个非常常见的简写是将{ print }
替换为1
,因为1
为真,{ print }
是默认操作。
要使用sed,我会选择这样的东西:
sed -i.bak '/#include "martini\.itp"/i\
#include "../dir1/dir2/martini1.itp"\
#include "../dir1/dir2/martini2.itp"\
#include "../dir1/dir2/martini3.itp"
d' file
这会插入您想要的行,然后d
删除原始行。使用-i.bak
创建原始文件的备份,这是我一直推荐的。
答案 1 :(得分:0)
您应该通过编写.
并将正则表达式分隔符从\.
更改为/
来转义:
,以防止正则表达式分隔符与文件路径发生冲突。最后,你应该得到这样的东西:
正则表达式:
$'s:#include "martini\.itp":#include "../dir1/dir2/martini_v2.0_lipids_all_201506.itp"\\\n#include "../dir1/dir2/martini_v2.0_ions.itp"\\\n#include "../dir1/dir2/martini_v2.0_solvents.itp":'
执行命令
sed -i '' $'s:#include "martini\.itp":#include "../dir1/dir2/martini_v2.0_lipids_all_201506.itp"\\\n#include "../dir1/dir2/martini_v2.0_ions.itp"\\\n#include "../dir1/dir2/martini_v2.0_solvents.itp":' topol.top
输出:
#include "../dir1/dir2/martini_v2.0_lipids_all_201506.itp"
#include "../dir1/dir2/martini_v2.0_ions.itp"
#include "../dir1/dir2/martini_v2.0_solvents.itp"
请注意,通过将newline
添加到正则表达式的开头并使用$
而不是\\\n
来逃避\n
,这里有一些技巧。
答案 2 :(得分:0)
你需要通过在每个实例之前放置\来转义“。”和/字符。对于换行符也是'$'/ n
sed -i 's/#include \"martini\.itp\"/#include \"\.\.\/dir1\/dir2\/martini1.itp\"'$'\\n#include \"\.\.\/dir1\/dir2\/martini2.itp\"\\n#include \"\.\.\/dir1\/dir2\/martini3.itp\"/g' topol.top