인코딩된 JSON 개체가 포함된 JSON 파일에서 값을 추출하는 방법

인코딩된 JSON 개체가 포함된 JSON 파일에서 값을 추출하는 방법

명령 출력:aws s3api get-bucket-policy --bucket bucketname

{
    "Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"S3SecureTransportPolicy\",\"Statement\":[{\"Sid\":\"ForceSSLOnlyAccess\",\"Effect\":\"Deny\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::amn/*\",\"Condition\":{\"Bool\":{\"aws:SecureTransport\":\"false\"}}},{\"Sid\":\"AWSCloudTrailAclCheck20150319\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudtrail.amazonaws.com\"},\"Action\":\"s3:GetBucketAcl\",\"Resource\":\"arn:aws:s3:::amn\"},{\"Sid\":\"AWSCloudTrailWrite20150319\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudtrail.amazonaws.com\"},\"Action\":\"s3:PutObject\",\"Resource\":\"arn:aws:s3:::amn/AWSLogs/405042254276/*\",\"Condition\":{\"StringEquals\":{\"s3:x-amz-acl\":\"bucket-owner-full-control\"}}}]}"
}

aws:SecureTransport이 JSON에서 키와 연결된 값 (이 경우 false) 및 키와 연결된 값을 grep(추출)해야 합니다 Effect.

나는 노력했다

aws s3api get-bucket-policy --bucket amn |
    grep -Po '"Bool": *\K"[^"]*"'

그리고

aws s3api get-bucket-policy --bucket amn |
    sed 's/.*\(aws:SecureTransport\)[^:]*:"\([0-9]*\)"'

어떻게 해야 하나요?

답변1

명령에서 얻은 JSON 문서에 다른 인코딩된 JSON 문서가 포함된 것으로 보입니다. 이 인코딩된 문서에서 데이터를 가져오려는 것 같습니다.

내부 문서를 얻으려면 다음을 사용할 수 있습니다 jq.

aws ... |
jq -r '.Policy'

Effect키를 포함하는 비트에서 키 값을 얻으려면 aws:SecureTransport문서를 다시 구문 분석해야 합니다.

aws ... |
jq -r '.Policy' |
jq -r '.Statement[] | select(.Condition.Bool."aws:SecureTransport").Effect'

마지막 jq호출은 배열의 모든 요소를 ​​반복하여 Statement이름이 지정된 키가 있는 요소를 찾습니다 .Condition.Bool."aws:SecureTransport". 그런 다음 Effect해당 요소와 관련된 키 값을 가져옵니다 Statement.

데이터에 대해 이 출력 값을 실행하십시오 Deny.

.Condition.Bool."aws:SecureTransport"false문서에서 해당 키의 값을 원하면 .Condition.Bool."aws:SecureTransport"위의 를 사용하세요 .Effect.

또는 두 번째 호출 대신 fromjson지시문을 사용하십시오 .jqjq

aws ... |
jq -r '.Policy | fromjson | .Statement[] | select(.Condition.Bool."aws:SecureTransport").Effect'

여기에서는 fromjson인코딩된 JSON 문서가 디코딩되어 후처리 단계로 전달됩니다.


참고로 내부적으로 인코딩된 JSON 문서는 다음과 같습니다( aws ... | jq -r '.Policy | fromjson').

{
  "Version": "2012-10-17",
  "Id": "S3SecureTransportPolicy",
  "Statement": [
    {
      "Sid": "ForceSSLOnlyAccess",
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::amn/*",
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    },
    {
      "Sid": "AWSCloudTrailAclCheck20150319",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::amn"
    },
    {
      "Sid": "AWSCloudTrailWrite20150319",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::amn/AWSLogs/405042254276/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    }
  ]
}

답변2

우선, 하지 마세요! jq에 설명된 대로 사용하세요.코살로난다의 답변. 이는 정규식을 조작하는 것보다 더 강력한 솔루션입니다. 즉, 이를 수행하는 한 가지 방법은 다음과 같습니다 grep.

aws ... | grep -oP 'aws:SecureTransport.":."\K.+?(?=\\")'

이것은 를 찾은 aws:SecureTransport다음 문자( .; \\이스케이프 슬래시를 작성하는 것보다 간단함)를 찾은 다음 ". \K지금까지 일치하는 모든 항목(따라서 일치하는 부분 aws:SecureTransport.":.")을 삭제합니다. 그런 다음 가장 짧은 문자열( )을 찾은 .+?다음 \"( ) 을 찾습니다 (?=\\").

샘플 출력이 포함된 파일에서 이 명령을 실행하면 다음이 제공됩니다.

$ grep -oP 'aws:SecureTransport.":."\K.+?(?=\\")' file
false

관련 정보