パラメータに基づいてXMLタグの一部の属性コンテンツを置き換える必要があります$1
。
次の入力があります。
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="OO CSS DPM PRI" enabled="true">
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="AA CSS DPM PRI" enabled="true">
testname
属性が次のような場合いいえ含まれ$1
、そうでなければenabled
値をfalse
。testname
する$1
)が含まれている場合はenabled
値をに置き換えますtrue
。
メモ:この例の属性よりも多くの属性が表示されることがあります。
考えてみましたが、sed
他のツールがうまくいくかもしれませんか?
答え1
まだ誰も言っていないので、そうします。 XML の解析に正規表現を使用しないでください。 XMLはコンテキスト言語ですが、正規表現はそうではありません。これは、いつか混乱して衝突が発生する可能性のある脆弱なコードを生成することを意味します。
より多くの例については、以下を参照してください。https://stackoverflow.com/questions/1732348/regex-match-open-tags-book-xhtml-self-contained-tags
パーサーを使用してください。それらはさまざまな言語で存在します。個人的に好きです。perl
タスクは次のとおりです。
#!/usr/bin/env perl
use strict;
use warnings;
#parser library
use XML::Twig;
#ingest data
my $twig = XML::Twig -> parse (\*DATA);
#iterate all tags <ThreadGroup>
foreach my $group ( $twig -> get_xpath('//ThreadGroup') ) {
#check testname regex match
if ( $group -> att('testname') =~ /AA/ ) {
#set enabled
$group -> set_att('enabled', 'true');
}
else {
#set disabled
$group -> set_att('enabled', 'false');
}
}
#pretty print options vary, see man page.
$twig -> set_pretty_print('indented_a');
$twig -> print;
__DATA__
<xml>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="OO CSS DPM PRI" enabled="true" />
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="AA CSS DPM PRI" enabled="true" />
</xml>
うん - それはい正規表現はこれを安全に実行できないため、XMLパーサーを使用する必要があります。属性の順序、改行、単項タグなど、XMLの多くの項目は意味的に同じですが、正規表現は異なります。しかし、パーサーはそれによって捕まらないでしょう。
必要に応じて、上記の内容を1行に減らすことができます。
perl -MXML::Twig -e 'XML::Twig -> new ( twig_handlers => { ThreadGroup => sub { $_ -> set_att("enabled", $_ -> att("testname") =~ /AA/ ? "true" : "false" ) } } ) -> parsefile_inplace("yourfile")'
あなたのシステム管理者チームは、これを行ったことに感謝しなければなりません(とは言えません)。どの正規表現ベースのソリューションは、ある日の明確な理由なくクラッシュする可能性があります。
最も簡単な例として、XMLは意味上次のとおりです。
<xml>
<ThreadGroup
enabled="true"
guiclass="ThreadGroupGui"
testclass="ThreadGroup"
testname="OO CSS DPM PRI"
/>
<ThreadGroup
enabled="true"
guiclass="ThreadGroupGui"
testclass="ThreadGroup"
testname="AA CSS DPM PRI"
/>
</xml>
または:
<xml>
<ThreadGroup enabled="true" guiclass="ThreadGroupGui" testclass="ThreadGroup"
testname="OO CSS DPM PRI"/>
<ThreadGroup enabled="true" guiclass="ThreadGroupGui" testclass="ThreadGroup"
testname="AA CSS DPM PRI"/>
</xml>
または:
<xml><ThreadGroup enabled="true" guiclass="ThreadGroupGui" testclass="ThreadGrou
p" testname="OO CSS DPM PRI"/><ThreadGroup enabled="true" guiclass="ThreadGroupG
ui" testclass="ThreadGroup" testname="AA CSS DPM PRI"/></xml>
または:
<xml
><ThreadGroup
enabled="true"
guiclass="ThreadGroupGui"
testclass="ThreadGroup"
testname="OO CSS DPM PRI"
/><ThreadGroup
enabled="true"
guiclass="ThreadGroupGui"
testclass="ThreadGroup"
testname="AA CSS DPM PRI"
/></xml>
これは、属性の順序付け、可能なタグのネスト、または予期しない場所で「一致する」他の部分文字列を扱う前です。
答え2
使用XMLスター:
#!/bin/sh
xml ed -u "//ThreadGroup[. = contains(@testname, '$1')]/@enabled" -v "true"
-u "//ThreadGroup[. = not(contains(@testname, '$1'))]/@enabled" -v "false"
XMLが有効であると仮定します。 (ルートタグを追加し、空の<SomeTag>
ノードを次のように適切に区別しました。<ThreadGroup>
/>
enabled
"hello"
する何):
$ cat data.xml
<SomeTag>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="OO CSS DPM PRI" enabled="hello"/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="AA CSS DPM PRI" enabled="hello"/>
</SomeTag>
$ sh script.sh "OO" <data.xml
<?xml version="1.0"?>
<SomeTag>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="OO CSS DPM PRI" enabled="true"/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="AA CSS DPM PRI" enabled="false"/>
</SomeTag>
答え3
ロジックを正しく理解すると、このsedコマンドはvalue内で指定された$ 1引数を検索し、testname
そのenabled
値を検索してfalseからtrueに置き換えます。 ()!
がない場合は、enabled
値をtrueからfalseに置き換えます。
sed '/ testname="[^"]*'"$1"'[^"]*"/ s/ enabled="false"/ enabled="true"/;
/ testname="[^"]*'"$1"'[^"]*"/!s/ enabled="true"/ enabled="false"/' input > output
属性名(testnameと有効)の前にスペースを追加し、文字クラスを使用して正規表現の一致を支援しようとしました[^"]
。
答え4
#/bin/sh
sed -r 'h
s/.*testname="([^"]*)".*/\1/
/\b'"$1"'\b/{ g; s/enabled="[^"]*"/enabled="true"/; b}
g
s/enabled="[^"]*"/enabled="false"/
' file