다음 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"
그런 다음 두 개의 프로세스를 실행합니다. 하나는 실행 중입니다.
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>,'
또한 예상 결과로 제공한 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