sed 명령을 사용하여 JSON 파일의 숫자를 MD5 해시로 바꾸려면 어떻게 해야 합니까?

sed 명령을 사용하여 JSON 파일의 숫자를 MD5 해시로 바꾸려면 어떻게 해야 합니까?

다음 예와 같은 줄이 포함된 JSON 형식의 대용량 로그 파일이 있습니다.

{"data_1":210,"target_number":1096748811,"extra_data":66}
{"data_1":0,"target_number":7130881445,"extra_data":56}
{"data_1":1712,"target_number":1098334917,"extra_data":48}
{"data_1":0,"target_number":3062674667,"extra_data":54}
{"data_1":53,"target_number":5110609228,"extra_data":246}

target_number값을 전체 파일의 MD5 해시로 바꾸고 싶습니다 .

sed다음 기본 구문을 사용하여 명령을 시도하고 있습니다 .

sed -i 's/target_number/target_number_md5/' input.log

위 예의 첫 번째 항목에 대한 예상 출력은 다음과 같습니다.

{"data_1":210,"target_number":620e25e6f054992308c564cb883e4940,"extra_data":66}

답변1

다음 명령을 사용하십시오밀러( ) JSON 입력을 구문 분석합니다("JSON 라인"을 읽으 려면 mlrMiller 버전 6 이상을 사용해야 함 ). 그런 다음 하위 명령을 사용하여 키 값을 수정합니다 . 수정은 표준 입력에 전달된 원래 값을 호출하여 수행됩니다. 그런 다음 응답에서 MD5 해시를 제외한 모든 항목을 제거하여 결과 문자열을 삭제합니다.--jsonl--jsonputtarget_numberopenssl md5

mlr --json put '
    $target_number = system("printf \"" . $target_number . "\" | openssl md5");
    $target_number = sub($target_number, ".*= ", "")' file

md5sumGNU coreutils를 사용하려면 openssl md5위의 내용을 md5sum --tag.

md5유틸리티(일반적으로 BSD 시스템에서 발견됨)를 사용하면 printf파이프를 피할 수 있습니다.

mlr --json put '
    $target_number = system("md5 -s \"" . $target_number . "\"");
    $target_number = sub($target_number, ".*= ", "")' file

질문의 예에서 위 명령 각각의 출력은 다음과 같습니다.

{ "data_1": 210, "target_number": "620e25e6f054992308c564cb883e4940", "extra_data": 66 }
{ "data_1": 0, "target_number": "f83d74be3dcb71d53263aefdf08203a9", "extra_data": 56 }
{ "data_1": 1712, "target_number": "56ae797ad2c16813d1a6168d28b58d89", "extra_data": 48 }
{ "data_1": 0, "target_number": "81394a193503036fad53b8a9d6ca2456", "extra_data": 54 }
{ "data_1": 53, "target_number": "6f01490a5dc694e51a69b79f7dd21c24", "extra_data": 246 }

MD5 해시는 십진수가 아닌 문자열이므로 생성된 JSON 문서에 문자열로 삽입됩니다.

mlr해당 옵션을 사용하면 Miller는 입력 파일을 생성된 문서로 바꿀 수 있습니다(즉, "제자리에서" 편집) -I.

target_number위의 각 명령은 호출 시 원시 값을 system()삭제하지 않고 사용하므로, 그렇게 하면 코드 주입 취약점이 발생합니다.

답변2

비슷한 문제를 해결하면서 이 질문을 찾았습니다. 루프 없이 해결하고 싶기 때문에 제공된 솔루션이 나에게 적합하지 않습니다.

루프 없이 문제를 해결하는 방법에 대한 개념 증명은 다음과 같습니다.

sed -E 's/(.*target_number":)([0-9]+)(.*)/echo "\1$(echo -n \2 | md5sum)\3"/e;s/  -//' "$inputFile"
  • -E: 기본 정규식 대신 확장 정규식을 사용하세요.
  • /e: 이 명령을 사용하면 쉘 명령 입력을 패턴 공간으로 파이프할 수 있습니다.

자세한 내용은 다음 소스를 확인하세요.https://www.gnu.org/software/sed/manual/sed.html

답변3

나는 스스로 답을 찾았습니다.

cat $inputFile | grep -Po '(?<="target_number":)[^,"]+' | while read i ; do
    sed -i "s/$i/$(echo -n $i | md5sum | cut -f 1 -d ' ')/g" $outputFile
done

관련 정보