XMLファイルがたくさんあります。tag1="alpha"
たとえば、XMLの特定のタグに基づいて各タグの名前を変更する必要があります。
私はそれに基づいてそれを行う方法を見つけました。一つ特定のタグの発生。
find . -maxdepth 1 -name '*.xml' -exec /rename.sh {} \;
#!/bin/bash
tag1=$(sed 's/.*tag1="\([^"]*\).*/\1/; q' "$1")
mv -v "$1" "$tag1.xml"
問題:一部のファイルには複数のtag1
タグがあります(例:)。これらのファイルの場合は、tag1="alpha"
tag1="beta"
tag1="omega"
同じファイルのコピーを別の名前で作成する必要がありますbeta.xml
。omega.xml
catの位置パラメータを試しましたが、うまくいきません(初心者です)。
ファイル構造の例:
<root xmlns:d="http://www.apple.com/DTDs/DictionaryService-1.0.rng">
<div class="div-entry"><d:entry xmlns:d="1.0.rng" id="m_en_gbus0240000" tag1="cudgel" class="entry">
<span class="hg x_xh0">
<span role="text" d:syl="1" class="hw">cudg.el<d:syl/></span>
<span prxid="cudgel_us_nv" prlexid="pron0014256.002" dialect="AmE" class="prx"> | <span d:prn="US" dialect="AmE" class="ph t_respell">ˈ;ke;je;l<d:prn/></span><span d:prn="IPA" soundFile="cudgel#_us_1" media="online" dialect="AmE" class="ph">ˈ;ke;dʒe;l<d:prn/></span> | </span>
</span>
<span class="sg">
<span id="m_en_gbus0240000.004" class="se1 x_xd0">
<span role="text" class="posg x_xdh">
<span d:pos="1" class="pos">
<span class="gp tg_pos">noun </span>
<d:pos/>
</span>
</span>
<span id="m_en_gbus0240000.005" class="msDict x_xd1 t_core">
<span d:def="1" role="text" class="df">a short, thick stick used as a weapon<span class="gp tg_df">. </span><d:def/></span>
</span>
<span class="gp x_xdt tg_se1"> </span>
</span>
<span id="m_en_gbus0240000.008" class="se1 x_xd0">
<span class="x_xdh">
<span role="text" class="posg">
<span d:pos="2" class="pos">
<span class="gp tg_pos">verb </span>
<d:pos/>
</span>
<span class="infg"><span class="gp tg_infg">(</span><span tag1="cudgels", <span tag1="cudgeling"<span class="pr"/>, <span tag1="cudgeled"<span class="pr"/>; <span class="lg"><span class="ge">British </span></span><span tag1="cudgels", <span tag1="cudgelling", <span tag1="cudgelled"<span class="gp tg_infg">) </span></span>
</span>
<span role="text" class="gg"><span class="gp tg_gg">[</span>with <span class="sy">object</span><span class="gp tg_gg">] </span></span>
</span>
<span id="m_en_gbus0240000.011" class="msDict x_xd1 t_core">
<span d:def="2" role="text" class="df">beat with a cudgel<d:def/></span>
<span role="text" class="gp tg_df">: </span>
<span role="text" class="eg">
<span class="ex"> they would lie in wait and cudgel her to death</span>
<span class="gp tg_eg">. </span>
</span>
</span>
</span>
<span class="gp tg_sg"> </span>
</span>
<span class="subEntryBlock x_xo0 t_phrases">
<span class="gp x_xoLblBlk ty_label tg_subEntryBlock">PHRASES </span>
<span id="m_en_gbus0240000.022" class="subEntry x_xo1">
<span class="x_xoh">
<span role="text" tag1="cudgel one's brains "
<span class="vg"><span class="gp tg_vg">(</span>also <span id="m_en_gbus0240000.037" tag1="cudgel one's brain"<span class="gp tg_vg">) </span></span>
</span>
<span id="m_en_gbus0240000.024" class="msDict x_xo2 t_core">
<span role="text" class="lg">
<span class="ge">British </span>
</span>
<span role="text" class="df">think hard about a problem</span>
<span role="text" class="gp tg_df">: </span>
<span role="text" class="eg">
<span class="ex"> she cudgeled her brains, trying to decide what had caused such an about-face</span>
<span class="gp tg_eg">. </span>
</span>
</span>
<span class="gp x_xot tg_subEntry"> </span>
</span>
<span id="m_en_gbus0240000.025" class="subEntry x_xo1">
<span role="text" tag1="take up the cudgels "
<span id="m_en_gbus0240000.026" class="msDict x_xo2 t_core">
<span role="text" class="df">start to defend or support someone or something strongly</span>
<span role="text" class="gp tg_df">: </span>
<span role="text" class="eg">
<span class="ex"> there was no one else to take up the cudgels on their behalf</span>
<span class="gp tg_eg">. </span>
</span>
</span>
</span>
</span>
<span role="text" class="etym x_xo0">
<span class="gp x_xoLblBlk ty_label tg_etym">ORIGIN </span>
<span class="x_xo1"><span class="dg"><span class="date">Old English </span></span><span class="italic">cycgel</span>, of unknown origin<span class="gp tg_etym">.</span></span>
</span>
</d:entry>
<div class="div-entry"><div>
</root>
答え1
なぜ使用しないのですか?xmlstarlet
フレーズを抽出
tag1
し、シェルスクリプトループから出力を処理します。
xmlstarlet select
複数のパス名を入力として受け入れるので、{} +
より効率的なsバリアントで使用できます。find
-exec
オペランド。常に true と評価されるため、-exec … {} +
ゼロ以外の終了状態では中断されません。tag1
変換されたフレーズとともにファイル名をリストするには、次のようにします。
# shellcheck shell=sh disable=SC2016
find . -maxdepth 3 -type f -name '*.xml' -exec \
xmlstarlet select --text -t \
--var tag1nodes='//@tag1[name(..)="span" or name(..)="div"]' \
--var allowchars -o 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' -b \
--var tag1cvt -o 'translate(normalize-space(),translate(.,$allowchars,""),"_")' -b \
-m 'set:distinct(dyn:map($tag1nodes,$tag1cvt))' \
-s 'A:T:-' '.' \
-f -o "${ofs:-$(printf '\t')}" -v '.' -n \
{} +
xmlstarlet select
コマンドの説明
select
最初の入力ファイルのルート要素にある名前空間定義(および事前定義されたEXSLTの名前空間)を使用してxsl
参照さsaxon
れる他のすべての名前空間は、オプションを使用して定義-N
する必要があります。- 変数は、または要素から構文(属性値)を収集します
tag1nodes
。tag1
div
span
推定デフォルトの名前空間または空の同じ場所に配置 - EXSLT
dyn:map
tag1cvt
この関数は引数(テキスト文字列として提供されたXPath式)を評価して、各構文を文字列にマップします。 - EXSLT
set:distinct
重複排除 - ソート順は、
A
昇順、T
拡張、未指定のケースの順序です。 tag1
その値がない場合、出力は生成されません。 (この場合は1が返されますselect
。)-C
使用する-t
XSLT 1.0スタイルシートを一覧表示するオプションを追加する前にselect
- ここで定義は
--var
読みやすくするために追加され、dyn:map
パラメータで簡単に置き換えることができます。 - パス名は
find
以下に由来します。推定いいえ'
(一重引用符)文字のため既知のエラー 存在するselect
- 空白(出力を処理するシェルスクリプトがデフォルト値を
IFS
使用する場合)read
いくつかのサンプル出力:
./dir-b/fum.xml cudgels
./dir-b/fum.xml take_up_the_cudgels
./fee.xml cudgel_ones_brain
./fee.xml cudgel_ones_brains
./fee.xml cudgeled
./fee.xml cudgeling
./fee.xml cudgelled
./fee.xml cudgelling
公開したファイルはXMLではありませんが、xmlstarlet
その内容を回復できます(-q
エラーリストを省略)。
xmlstarlet -q format -R junk > file.xml
答え2
この質問は2つの部分に分かれているようです。まず、tag1が表示されるすべてのエントリを見つけることです。 2番目の部分はそれを使用してxmlファイルの名前を変更する方法です。この2番目の部分の条件は、現在の投稿では完全には明確ではありません。
これはソリューションの最初の部分にすぎません。
$ sed 's/tag1/\ntag1/g' input_file | sed -n '/tag1/p' | cut -d '"' -f2
cudgel
cudgels
cudgeling
cudgeled
cudgels
cudgelling
cudgelled
cudgel one's brains
cudgel one's brain
take up the cudgels