1

以下の要件があります。

サンプルファイル.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>

このスクリプトを試して、2 つの文字列 (文字列を含む) の間にテキスト ( . password. ) を見つけて、それをプレースホルダーに置き換えます。cmdlinepasswd プレースホルダーに「/」という特殊文字が含まれていると、必ず失敗します。

sed -ie "/$datasource/,/password*/ {s/.*password.*/\tpassword=\"$cmdlinepasswd\"/;}"    file.txt

datasource=jdbc/myDBPool1 cmdlinepasswd=new/passwd と仮定

私はスクリプトを書くのが初めてで、助けていただければ幸いです。ありがとうございました。

4

2 に答える 2

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>"た場合はそのレコードのパスワードを置き換えます。

シェル変数が既にある場合

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
于 2013-08-24T20:53:34.847 に答える
0

を使用する 1 つの方法。チェック/置換する変数と入力ファイルの 3 つの引数を受け取ります。正規表現の多くの特殊文字をエスケープする引数にquotemeta() を実行するため、 よりも優れています。\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ですが、このソリューションは私のテストではうまくいくようです。

于 2013-08-24T20:44:27.133 に答える