任意のシェルスクリプトからコマンドを抽出したいと思います。使ったモルビック(方へマイケル・ホーマーアドバイスを受けてください! )シェルスクリプトから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
ドキュメント内の各エンティティに対して繰り返され、各エンティティの種類をテストして配列であることを確認します。最初の要素である文字列を含む見つかった配列ごとに、2番目の要素のCmdName_Word
2番目の要素(探しているコマンド名)を抽出します。
この表現は次のように短縮できます。
jq -r '.. | select(.[0]? == "CmdName_Word")[1][1]' file
...可能な場合.[0]
に使用され、配列の場合は現在のエンティティになります。私もselect()
自分で.[1][1]
使ってみましたselect()
。