임의의 쉘 스크립트에서 명령을 추출하고 싶습니다. 나는 사용했다모르빅(쪽으로마이클 호머조언을 받아보세요! ) 쉘 스크립트에서 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):
(운영 체제에 따라 docker를 설치하십시오)
docker pull colisanr/morbig:latest
사용 편의성을 위해 쉘 함수를 정의하십시오.
morbig () { D=$(cd "$(dirname "$1")"; pwd) B=$(basename "$1") docker run \ -v "$D":/mnt \ colisanr/morbig:latest --as simple /mnt/"$B" }
셸 스크립트가 포함된 디렉터리에 UID 1000으로 쓸 수 있는지 확인하세요(Docker 컨테이너는 UID 1000이 있는 컨테이너 내에서 사용자 "opam"으로 실행됨).
morbig your-shell-script-here.sh
생성된
your-shell-script-here.sh.sjson
JSON은 셸 스크립트와 동일한 디렉터리에 있습니다.
답변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()
.