我有下面提到的要求。
示例file.txt ::
<?xml version='1.0' encoding='utf-8'?>
<Server port="${shutdown.port}" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="com.springsource.tcserver.serviceability.rmi.JmxSocketListener"
port="${jmx.port}"
bind="127.0.0.1"
useSSL="false"
passwordFile="${catalina.base}/conf/jmxremote.password"
accessFile="${catalina.base}/conf/jmxremote.access"
authenticate="true"/>
<Listener className="com.springsource.tcserver.serviceability.deploy.TcContainerDeployer" />
<GlobalNamingResources>
<Resource
name="jdbc/myDBPool1"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
description="Oracle Datasource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
url="jdbc:oracle:thin:@localhost:<dbanme>"
user="myusername"
password="somepassword1"
validationQuery="SELECT 1 FROM DUAL"
/>
<Resource
name="jdbc/myDBPool2"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
description="Oracle Datasource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
url="jdbc:oracle:thin:@localhost:<dbanme>"
user="myusername"
password="somepassword2"
validationQuery="SELECT 1 FROM DUAL"
/>
<Resource
name="jdbc/myDBPool3"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
description="Oracle Datasource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
url="jdbc:oracle:thin:@localhost:<dbanme>"
user="myusername"
password="somepassword3"
validationQuery="SELECT 1 FROM DUAL"
/>
</GlobalNamingResources>
<Service name="Catalina">
<Executor name="tomcatThreadPool" namePrefix="tomcat-http--" maxThreads="300" minSpareThreads="50"/>
<Connector executor="tomcatThreadPool"
port="${http.port}"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="${https.port}"
acceptCount="100"
maxKeepAliveRequests="15"/>
<Engine name="Catalina" defaultHost="localhost">
<!--
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true" deployOnStartup="true" deployXML="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>
</Engine>
</Service>
</Server>
我正在尝试使用此脚本在两个字符串(包括字符串)之间找到一些文本(。密码。),然后用占位符替换它。每当我的cmdlinepasswd占位符有特殊字符时,说“/”字符就会失败。
sed -ie "/$datasource/,/password*/ {s/.*password.*/\tpassword=\"$cmdlinepasswd\"/;}" file.txt
假设 数据源= JDBC / myDBPool1 cmdlinepasswd =新/ passwd的
我是脚本新手,任何帮助都将不胜感激。 谢谢。
答案 0 :(得分:1)
这应该这样做:
awk -v RS= -v ORS='\n\n' -v datasource="jdbc/myDBPool1" -v cmdlinepasswd="new/passwd" '
$0 ~ "^[[:space:]]*<Resource.*name=\"" datasource "\"" {
sub(/password="[^"]+"/,"password=\"" cmdlinepasswd "\"")
} 1' file
它只查找以<Resource
后跟name="<your datasource variable value>"
开头的记录,如果找到,则会替换该记录中的密码。
如果你已经有了shell变量
datasource="jdbc/myDBPool1"
cmdlinepasswd="new/passwd"
将它们传递给awk:
awk -v RS= -v ORS='\n\n' -v datasource="$datasource" -v cmdlinepasswd="$cmdlinepasswd" '
$0 ~ "^[[:space:]]*<Resource.*name=\"" datasource "\"" {
sub(/password="[^"]+"/,"password=\"" cmdlinepasswd "\"")
} 1' file
答案 1 :(得分:0)
使用perl的一种方法。它接受三个参数,即检查/替换的变量和输入文件。它比sed更好,因为它对参数进行了引用(\Q
),它可以逃避正则表达式的许多特殊字符。
perl -pe '
## Get arguments but input file.
BEGIN { ($datasource,$cmdlinepasswd) = (shift,shift) }
## Get a range from resource name until the line with the password.
if ( $range = ( m/=\s*"\Q${datasource}"/ ... /password\s*=/ ) ) {
## "E0" points to last line (that contains the password, so
## change it.
if ( q|E0| eq substr $range, -2 ) {
s/(=\s*").*("\s*)$/$1${cmdlinepasswd}$2/;
}
}
' "$datasource" "$cmdlinepasswd" infile
使用您的示例输入数据,它会产生(仅显示已修改的密码部分,其余部分保持不变):
<?xml version='1.0' encoding='utf-8'?>
<Server port="${shutdown.port}" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="com.springsource.tcserver.serviceability.rmi.JmxSocketListener"
port="${jmx.port}"
bind="127.0.0.1"
useSSL="false"
passwordFile="${catalina.base}/conf/jmxremote.password"
accessFile="${catalina.base}/conf/jmxremote.access"
authenticate="true"/>
<Listener className="com.springsource.tcserver.serviceability.deploy.TcContainerDeployer" />
<GlobalNamingResources>
<Resource
name="jdbc/myDBPool1"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
description="Oracle Datasource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
url="jdbc:oracle:thin:@localhost:<dbanme>"
user="myusername"
password="new/passwd"
validationQuery="SELECT 1 FROM DUAL"
/>
...
注意:看到您的编辑后,使用xml
解析器是更好的选择,但此解决方案似乎适用于我的测试。