Bash

使用 sed 替換 XML 標記內容的問題

  • December 31, 2021

我有以下 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>

我可能做錯了什麼?TIA。

sha1sum正在評估常量字元串 “\1” 的 SHA-1,而不是第一個 SED 正則表達式匹配:

$ echo \\1 | sha1sum
cbcac786fef5abeb39fe473ab6abe554978a8156  -

shell 在執行命令(在本例中為 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"

然後它執行兩個程序,一個正在執行

cat test.xml

和另一個跑步

sed "s/>[+]\([0-9][0-9]*\)<\/value>/>+cbcac786fef5abeb39fe473ab6abe554978a8156<\/value>/g"

將第一個程序的 STDOUT 通過管道傳輸到第二個程序的 STDIN。

為了使您嘗試執行的操作,sed必須能夠從sed. 我不相信sed可以做到這一點,所以你必須以其他方式做到這一點。

你可以這樣做sed,例如這是一種方法

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>,'

您也沒有在括號中包含第一個sed匹配字元串的“+”,從您作為預期結果提供的 SHA1 總和中,我相信您希望包含“+”,所以我也更正了.

不要使用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>

引用自:https://unix.stackexchange.com/questions/683572