このXMLを次に変換したいと思います。確認する互いに接続された線。これにより、後で特定の行だけをキャッチできます。このXMLが属性を使用した場合、データはすでに1行にあります。これを行うためにXSLTを使用したくありません。 grep、sed、awk、xmlstarlet、xpathが良いでしょう。
したがって、1行にが含まれている場合は、"<instruction>"
次の4行を取得し、すべて1行に配置する必要があります。カンマはありません。次のようになります。
投稿された質問とは異なります。ここ:「参加」順序を開始する日付としてモードを設定します。
awk '
/\<instruction\>/ && line {print line; line=""}
{line = line ? line" "$0 : $0}
END {print line}
'
これにより、行が閉じるタグに縮小されますが、閉じるタグ行自体は導入されません。
プラットフォームは Windows 2012R2 サーバーにあります。 Gnuユーティリティがインストールされます。ファイルサイズは約100kです。
<instruction>
<name>AAAAA</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<instruction>
<name>BBBBB</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<instruction>
<name>CCCCC</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<routing/>
<phantom>False</phantom>
<AssemblyHistory/>
必要な出力:(改行できますが、ディレクティブ要素はすべて1行にする必要があります)
<instruction><name>AAAAA</name><value>WHITE</value><type>0</type></instruction> <instruction><name>BBBBB</name><value>WHITE</value><type>0</type></instruction> <instruction><name>CCCCC</name><value>WHITE</value><type>0</type></instruction> <routing/> <phantom>False</phantom> <AssemblyHistory/>
同様の例(無効なXML)
data line 2
cust:
tommy
smith
123 main
endcust
data line 16
TRACE: error at xy123
cust:
mary
smith
444 broadway
endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf tty0
data line 2
cust: tommy smith123 main endcust
data line 16
TRACE: error at xy123
cust:mary smith444 broadway endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf tty0
行を省略せずにファイル全体を標準出力にコピーします。 "cust:"を見つけたら、次のいずれかを実行できます。 1)次の4行を結合するか、2)「終了」が見つかるまで行を結合します。
同様ですが、今回はXMLツールを使用できません。それでは、このような状況が発生した場合はどうすれば解決しますか?最も重要な質問がXMLであれば良いです。そうでない場合は、2番目の例を使用してください。
答え1
sedの範囲演算子を使用して問題を解決できますが、その前に同じ行でトークンを処理してフラグを解除する必要があります。同じ行にある複数のタグも処理されません。
sed -e '
s/^[[:blank:]]*//
\|<instruction>.*</instruction>|b
\|<instruction>|,\|</instruction>|!b
H;\|</instruction>|!d
s/.*//;x;s/\n[[:blank:]]*//g;s/^\n//
' input_xml_lookalike_file
答え2
grep/sed/awkを使用したいのはなじみがあるからです。しかし、それが仕事に適したツールになるわけではありません。ただ使い方を知ってもドライバを使って釘を打つのは賢明な考えではありません。
これを達成するには、XSLTやXQueryなどのXML対応ツールが必要です。 (まず、タグに<instruction>
空白がまったく含まれないと思うのはなぜですか?そしてディレクティブ要素の内容は常に4行にわたって広がっていると思いますか?)
StackOverflowの多くのユーザーは、特定の方法でフォーマットされたXMLを生成する方法を尋ね、これによりXMLツールの選択が制限されます。なぜこれが必要なのかを尋ねる場合は、常に誰かがawk、grep、PerlなどのXMLを認識しないツールを使用してXMLを読み取るアプリケーションを作成したと答えます。これにより、XMLの全体的なポイント(およびXMLが提供するすべての相互運用性の利点)が失われます。
答え3
value
instruction
たとえば、値が使用される子name
ノードもある各ノードの子ノード値を抽出します。Exterior Color
XMLスター:
xmlstarlet sel -v '//instruction[name = "Exterior Color"]/value' -nl file.xml
与えられたファイル
<?xml version="1.0"?>
<AssemblyHistory>
<routing>
<instruction>
<name>Interior Finish</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<instruction>
<name>Exterior Color</name>
<value>WHITE</value>
<type>0</type>
</instruction>
<instruction>
<name>Base Vinyl Color</name>
<value>WHITE</value>
<type>0</type>
</instruction>
</routing>
<phantom>False</phantom>
</AssemblyHistory>
これにより文字列が返されますWHITE
。
以下は、すべてのノードにname
対応する各値を返します。WHITE
instruction
xmlstarlet sel -t -v '//instruction[value = "WHITE"]/name' -nl file.xml
答え4
これはほとんど動作します。
awk 'BEGIN {RS="<instruction>"; FS="\n"; OFS=""} NR>1 {$1=RS; NF--; print}'
ただし、前の行をスキップして/ instructionタグを表示しても結合は中断されません。
input:
LINE 0
LINE 1
LINE 2
<instruction>
<name>Glass SQFT</name>
<value>7.02</value>
<type>0</type>
</instruction>
LINE 3
output:
<instruction><name>Glass SQFT</name><value>7.02</value><type>0</type></instruction>LINE 3