次のXMLフラグメントがあります。
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+380554446363</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+380554446364</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+380554446365</value>
<value>
以下を使用して、タグコンテンツをSHA-1ハッシュに置き換えようとしました。
cat test.xml | sed "s/>[+]\([0-9][0-9]*\)<\/value>/>+$(echo \\1 | sha1sum | cut -f1 -d' ')<\/value>/g"
見つかったすべてのケースが同じエラー値に置き換えられているため、失敗します。
期待される:
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">34df370575e3528b31daef8633cb539119a3b028</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">d93767c769fd51bcf9eb25f95932559b24bae812</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">20338c1f048bed553b6cce76eaf1d388ba7686f5</value>
得る:
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+cbcac786fef5abeb39fe473ab6abe554978a8156</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+cbcac786fef5abeb39fe473ab6abe554978a8156</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+cbcac786fef5abeb39fe473ab6abe554978a8156</value>
私は何を間違えることができましたか?ティア。
答え1
sed
XMLを使用または編集しないでくださいawk
。xml
Pythonなどの適切なパーサーを使用してくださいxml.etree
。
input.xml
:
<values>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+380554446363</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+380554446364</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">+380554446365</value>
</values>
#!/usr/bin/env python3
import hashlib
import xml.etree.ElementTree as ET
tree = ET.parse('input.xml')
root = tree.getroot()
for value in root:
value.text = hashlib.sha256(value.text.encode('utf-8')).hexdigest()
tree.write('output.xml')
output.xml
:
<values>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">4b2bdff20d17dc4ae7ad99937399530b39bd7a63f7348375c547d01565c11898</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">8d3b1452d83ef803f8043eaddbe2fc58b0fd42c8ad5abc554e78796548f75ddb</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">06bd986417875e536401306180c51b7ded4eeab179933e0026a103bc8dc9eee7</value>
</values>
答え2
sha1sum
最初のSED正規表現一致ではなく、定数文字列 "\ \ 1"のSHA-1を評価します。
$ echo \\1 | sha1sum
cbcac786fef5abeb39fe473ab6abe554978a8156 -
シェルは、コマンド(この場合はsed)を実行する前に、さまざまな拡張(コマンドの置き換えなど)のすべてを実行します。したがって、皮が膨張する。
cat test.xml | sed "s/>[+]\([0-9][0-9]*\)<\/value>/>+$(echo \\1 | sha1sum | cut -f1 -d' ')<\/value>/g"
到着
cat test.xml | sed "s/>[+]\([0-9][0-9]*\)<\/value>/>+cbcac786fef5abeb39fe473ab6abe554978a8156<\/value>/g"
次に、2つのプロセスを実行します。 1つは実行中です。
cat test.xml
もう一つは実行中です。
sed "s/>[+]\([0-9][0-9]*\)<\/value>/>+cbcac786fef5abeb39fe473ab6abe554978a8156<\/value>/g"
最初のプロセスのSTDOUTは、2番目のプロセスのSTDINにパイプされます。
実行したい操作が機能するには、sed
内から別の実行可能ファイルを実行できる必要がありますsed
。私はそれができると信じていないので、sed
他の方法でやるべきです。
を使用してこれを行うことができますsed
。たとえば、これは1つの方法です。
for a in `cat test.xml | sed -E 's,^.*>(\+[0-9]+)<\/value>$,\1,'`; do echo "$a" | sha1sum | cut -f1 -d' '; done >2nd
cat test.xml | sed -E 's,>\+[0-9]+</value>$,>,' >1st
paste -d '' 1st 2nd | sed -E 's,$,</value>,'
また、期待される結果として提供されたSHA1の合計に基づいて、最初の一致文字列の括弧に「+」を含めませんでした。sed
「+」を含めたかったのでこの部分も修正しました。
答え3
GNU sed 代替コマンドには、変更されたパターン/e
空間とも呼ばれる s/// の rhs である vash コードで実行される修飾子があります。
sed -E "
s/'/&\\\\&&/g
s:(<.*>)([+][0-9]+)(</value>.*):printf '%s%s%s' '\\1' \"\$(echo '\\2'|sha1sum|cut -d' ' -f1)\" '\\3':e
" test.xml
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">34df370575e3528b31daef8633cb539119a3b028</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">d93767c769fd51bcf9eb25f95932559b24bae812</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">20338c1f048bed553b6cce76eaf1d388ba7686f5</value>
答え4
次のシステムを使用する場合xmlstarlet次にコンパイルcrypto
拡大する話せる機能:
xmlstarlet sel -N crypto='http://exslt.org/crypto' \
-t -m '//value' -e '{name()}' -c '@*' -v 'crypto:sha1(.)' -b -n \
file.xml
出力:
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">3bacaac1e104d7bfde5ff462d461d3b4b917c037</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">808b3e7bb8c8c7c06c328a082bac64205837531b</value>
<value id="1" creatorId="0" creationTime="1639487132" expirationTime="1639573532">8c31811a3b8d816f719ad5c78b58810b9b6cd4b7</value>
ここで、チェックサムは、改行を含むテキストでは計算されないため、目的の出力とは異なります。
xmlstarlet transform --show-ext 2>&1 | grep crypto
私の最終出力で次を実行します。
{http://exslt.org/crypto}md4
{http://exslt.org/crypto}sha1
{http://exslt.org/crypto}md5
{http://exslt.org/crypto}rc4_decrypt
{http://exslt.org/crypto}rc4_encrypt