morbig에서 생성된 JSON 파일에서 CmdName_Word 추출 - Word

morbig에서 생성된 JSON 파일에서 CmdName_Word 추출 - Word

임의의 쉘 스크립트에서 명령을 추출하고 싶습니다. 나는 사용했다모르빅(쪽으로마이클 호머조언을 받아보세요! ) 쉘 스크립트에서 JSON 파일을 생성합니다.

예를 들어 다음 셸 스크립트는 다음과 같습니다.

#!/bin/sh
echo hi
false || echo something
true && echo something

결과는 다음 JSON입니다.

[
  "Program_LineBreak_CompleteCommands_LineBreak",
  [ "LineBreak_Empty" ],
  [
    "CompleteCommands_CompleteCommands_NewlineList_CompleteCommand",
    [
      "CompleteCommands_CompleteCommands_NewlineList_CompleteCommand",
      [
        "CompleteCommands_CompleteCommand",
        [
          "CompleteCommand_CList",
          [
            "CList_AndOr",
            [
              "AndOr_Pipeline",
              [
                "Pipeline_PipeSequence",
                [
                  "PipeSequence_Command",
                  [
                    "Command_SimpleCommand",
                    [
                      "SimpleCommand_CmdName_CmdSuffix",
                      [
                        "CmdName_Word",
                        [ "Word", "echo", [ [ "WordName", "echo" ] ] ]
                      ],
                      [
                        "CmdSuffix_Word",
                        [ "Word", "hi", [ [ "WordName", "hi" ] ] ]
                      ]
                    ]
                  ]
                ]
              ]
            ]
          ]
        ]
      ],
      [ "NewLineList_NewLine" ],
      [
        "CompleteCommand_CList",
        [
          "CList_AndOr",
          [
            "AndOr_AndOr_OrIf_LineBreak_Pipeline",
            [
              "AndOr_Pipeline",
              [
                "Pipeline_PipeSequence",
                [
                  "PipeSequence_Command",
                  [
                    "Command_SimpleCommand",
                    [
                      "SimpleCommand_CmdName",
                      [
                        "CmdName_Word",
                        [ "Word", "false", [ [ "WordName", "false" ] ] ]
                      ]
                    ]
                  ]
                ]
              ]
            ],
            [ "LineBreak_Empty" ],
            [
              "Pipeline_PipeSequence",
              [
                "PipeSequence_Command",
                [
                  "Command_SimpleCommand",
                  [
                    "SimpleCommand_CmdName_CmdSuffix",
                    [
                      "CmdName_Word",
                      [ "Word", "echo", [ [ "WordName", "echo" ] ] ]
                    ],
                    [
                      "CmdSuffix_Word",
                      [
                        "Word",
                        "something",
                        [ [ "WordName", "something" ] ]
                      ]
                    ]
                  ]
                ]
              ]
            ]
          ]
        ]
      ]
    ],
    [ "NewLineList_NewLine" ],
    [
      "CompleteCommand_CList",
      [
        "CList_AndOr",
        [
          "AndOr_AndOr_AndIf_LineBreak_Pipeline",
          [
            "AndOr_Pipeline",
            [
              "Pipeline_PipeSequence",
              [
                "PipeSequence_Command",
                [
                  "Command_SimpleCommand",
                  [
                    "SimpleCommand_CmdName",
                    [
                      "CmdName_Word",
                      [ "Word", "true", [ [ "WordName", "true" ] ] ]
                    ]
                  ]
                ]
              ]
            ]
          ],
          [ "LineBreak_Empty" ],
          [
            "Pipeline_PipeSequence",
            [
              "PipeSequence_Command",
              [
                "Command_SimpleCommand",
                [
                  "SimpleCommand_CmdName_CmdSuffix",
                  [
                    "CmdName_Word",
                    [ "Word", "echo", [ [ "WordName", "echo" ] ] ]
                  ],
                  [
                    "CmdSuffix_Word",
                    [ "Word", "something", [ [ "WordName", "something" ] ] ]
                  ]
                ]
              ]
            ]
          ]
        ]
      ]
    ]
  ],
  [ "LineBreak_Empty" ]
]

다음 출력을 보고 싶습니다.

echo
false
echo
true
echo

...이제 기본 명령의 모든 매개변수, 옵션 및 매개변수를 무시합니다. 출력 명령의 순서는 중요하지 않습니다. 내보내기 전에(그리고 나중에 저장하기 전에) 쉽게 고유하게 만들 수 있다면 |sort -u보너스 포인트입니다 .

나는 이것을 했다:

< simple.json jq flatten | grep -A2 CmdName_Word

하지만 이는 잘못된 접근 방식처럼 느껴집니다. "CmdName_Word" 다음에 "Word" 뒤에 오는 단어를 알려주고 싶은데 jq어떻게 해야 할지 모르겠습니다.


이 단계를 로컬에서 재현하려는 경우(에서 발췌)https://github.com/colis-anr/morbig):

  1. (운영 체제에 따라 docker를 설치하십시오)

  2. docker pull colisanr/morbig:latest

  3. 사용 편의성을 위해 쉘 함수를 정의하십시오.

     morbig () {
       D=$(cd "$(dirname "$1")"; pwd)
       B=$(basename "$1")
       docker run \
         -v "$D":/mnt \
         colisanr/morbig:latest --as simple /mnt/"$B"
     }
    
  4. 셸 스크립트가 포함된 디렉터리에 UID 1000으로 쓸 수 있는지 확인하세요(Docker 컨테이너는 UID 1000이 있는 컨테이너 내에서 사용자 "opam"으로 실행됨).

  5. morbig your-shell-script-here.sh

  6. 생성된 your-shell-script-here.sh.sjsonJSON은 셸 스크립트와 동일한 디렉터리에 있습니다.

답변1

$ jq -r '.. | select(type == "array" and .[0] == "CmdName_Word") | .[1][1]' file
echo
false
echo
true
echo

여기에 사용된 표현식은 jq문서의 각 엔터티에 대해 반복되며 각 엔터티의 유형을 테스트하여 배열인지 확인합니다. 첫 번째 요소인 string 이 있는 발견된 각 배열에 대해 CmdName_Word두 번째 요소의 두 번째 요소(찾고 있는 명령 이름)를 추출합니다.

이 표현은 다음과 같이 단축될 수 있습니다.

jq -r '.. | select(.[0]? == "CmdName_Word")[1][1]' file

... 가능한 경우 .[0]에 사용되며 배열인 경우 현재 엔터티가 됩니다. 저도 select()직접 .[1][1]사용해 봤습니다 select().

관련 정보