我正在尝试匹配用sed替换多行块,我无法弄清楚..
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'testblah', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
我认为最简单的方法就是这样;
sed -i "s/^DATABASES\s?+=\s?+{$+8/test/" settings.py
简而言之,我想找到DATABASES = {
包含捕获中的以下8行,并将其替换为其他行。
关于什么是错的任何想法?
答案 0 :(得分:2)
$ cat > f.sed
/^DATABASES/,/^}/c\
\
A block of replacement\
...text.
$ sed -f f.sed test.txt
更新:一般来说,应该将SO答案视为采取的方向,而不是完成食谱。正如Brian指出的那样,正则表达式中的细节将影响答案的一般性和具体程度。您可能希望更多地提出任何一个或另一个w.r.t.任何模式类...
答案 1 :(得分:1)
正则表达式不足以准确匹配大括号对。你需要一个无上下文语法。这是最接近原始问题的问题,sed可以做到:
将以DATABASES
开头的行替换为test
sed -n -e '/^DATABASES/i test' -e '/^DATABASES/{n;n;n;n;n;n;n;n;n;n;};p' settings.py
答案 2 :(得分:1)
如果您没有被迫使用sed,那么grep -A 8'你的正则表达式'可能会起作用。 (GNU grep)
答案 3 :(得分:1)
这可能在perl中比在sed中更容易解决。首先,做多线比赛是微不足道的。
perl -0777 -pe 's/foo.*?bar/glarch/sg'
但另一方面,你实际上可以使用嵌套括号进行递归匹配,我担心你可能需要它。
此外,由于perl使用ERE并且sed使用BRE,因此您将不再需要这么多反斜杠,因此您可以更轻松地使用它。
此外,支持所有\s+
类型的内容。
另外,如果这是UTF-8文本,你仍然可以;只需添加-CSD
类型的命令行标志。
另外,有一个名为s2p的sed-to-perl翻译器,所以你知道它是一个合适的超集。
天哪,确实很多也是。 ☺