我需要编写一个简单的脚本,用另一个文件的内容替换配置文件中的文本块。
让我们假设有以下简化的文件:server.xml
<?xml version='1.0' encoding='UTF-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="80" protocol="HTTP/1.1"/>
<Engine name="Catalina" defaultHost="localhost">
<!-- BEGIN realm -->
<sometags/>
<sometags/>
<!-- END realm -->
<Host name="localhost" appBase="webapps"/>
</Engine>
</Service>
</Server>
realm.xml
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
我想运行一个脚本,让realm.xml
替换<!-- BEGIN realm -->
和<!-- END realm -->
行之间的内容。如果realm.xml
发生了变化,那么每当脚本再次运行时,它将再次用realm.xml
的新内容替换这些行。这是为了在/etc/init.d/tomcat
中运行,在多个安装上启动服务时,域将是不同的。
我不太确定如何简单地使用awk
或sed
来实现这一点。
8条答案
按热度按时间hmmo2u0o1#
给予这个试试:
vi4fp9gy2#
(OK,这不使用awk或sed...我认为这不是一个唯一的要求:-)
pgpifvop3#
可以使用awk
realm.xml作为第一个文件传递给awk。FNR==NR表示获取传入的第一个文件的记录并存储到变量
_
。awk将处理下一个文件一次FNR!=NR.如果awk找到/BEGIN realm/
,则打印BEGIN realm
行,然后打印_
中存储的内容。通过将标志(f)设置为1,将不会打印BEGIN realm
之后的其余行,直到检测到/END realm/
。qlfbtfca4#
我创建的这个小片段怎么样:
第一个命令打印最多
<!- BEGIN realm -->
的行,第二个命令打印从<!-- END realm -->
开始的行,第三个命令将文本附加到文件'realm.xml'中。如果我能简化<!- BEGIN realm -->
和<!-- END realm -->
之间的线的删除,而不删除标记线,那就太简单了。而且它可以用sed完成inplace
!!!r1zk6ea15#
您还可以使用艾德命令(参见http://wiki.bash-hackers.org/howto/edit-ed):
4dc9hkyq6#
我遇到了同样的需求(因此找到了这个问题)。在使用sed和awk太久之后,我最终意识到使用现代的,可读的,可理解的,广泛可用的语言(如Python)没有什么错:
我认为sed和awk已经风光不再了。它们曾经很有用,但现在很少有人能在没有文件帮助的情况下阅读或写作。
(来源:互联网)
dy1byipe7#
我无法让Dennis解决方案在OSX上轻松工作(它的BSD sed略有不同)。我发现了另一个解决方案,我能够在Linux和OSX上工作(我有一个混合环境)。superuser.com上的原始版本只能在Linux上工作,我在这里修复了它:
下面是Dennis代码的一个版本,它也可以在OS X上运行(使用多行代码):
这两个代码都在stdout上打印输出。使用重定向,或者添加选项'-i'(在Linux上)或'-i“"'(在BSD/OS X上)以内联方式替换文件。
xjreopfe8#
简单的sed和稍微复杂一点的awk解决方案:
skip
开始未设置skip
)skip
,则打印行skip
)