シェルにワンライナーを記述するほど、2つの重要なアイデアが浮かび上がります。
- これは、「直接プログラミング」、つまりコンピューターに何をすべきかを伝えるための非常に強力なツールです。
- 単一行のほとんどはgrep / awk / cut / trに専念しており、以前のユーティリティの出力を何らかの形で取り出して人間の形にします。
パイプモデルは驚くべきものであるにもかかわらず、2番目の段落の出力で必要なフィールドをキャッチするための完全にダーティなハック(「ここで、awk -F、 '{print $ 2}'を使用して特性コンマを使用して必要なフィールドを選択できます... )手順を喜びのために物議を醸し、確かに読めないようにします。
別の深刻な問題:シェルは関数型プログラミングから非常に多くのイディオムを提供するという事実にもかかわらず、外部プログラムの実行結果によってリストをフィルタリングするイディオムがありません。 つまり、リストを「挽く」ことができます。 しかし、あるプログラムが「成功」を返した要素のみをリストに残します-いいえ。
同時に、敵対的であまりよく書かれていない環境があります-powershell(Windows)。 そこでは、彼らは良いアイデアを取りましたが(パイプはテキストではなくオブジェクトを送信します)、次の2つの点でそれを台無しにしました。
- Windowsの非人間工学的コンソール(
Shift-PgUpどこで、新しいバージョンではCtrl-PdUpと言います) - メソッドを適切に機能させるために、.netにアクセスして学習することをお勧めします。
- ほとんどのオペレーティングシステムの不足
暖かいLinux Linuxシェルのパイプにオブジェクトを入れたいです。 ハンドキャンディー(タイピングが少ない)、アイキャンディー(見た目が良い)および人間工学に基づいた全体的な使用。 また、「新しいアプローチ」と古い、つまり通常のテキストパイプを組み合わせることもできます。
アイデア
パイプスタイルの構造化データを操作できるツールのセットを作成する必要があります。 明らかな選択肢は
XML JSONです。
必要なもの:
- 標準入力形式を受け入れ、それらをjsonに変換するユーティリティ。
- パイプがjsonを操作できるようにするユーティリティ。
- jsonを「通常の」形式に変換するユーティリティ。
この場合、ユーザーは画面にjsonを表示しませんが、jsonを操作できます。
種子用
(理解のために、私は長いユーティリティ名を書きます。実際には、短い略語、つまりjson-get-objectではなく、jgoやjgのようなものになります)
タイプを判別するために管理されたファイルのファイルのみを表示します。
ls -la | ls2json | json-filter 'filename' --exec 'file {} >/dev/null' | json-print
特定のサイトから認証用のトークンをダウンロードし、jsonからそれを取り出して環境変数に設定します。その後、リストをダウンロードし、regexpによって著者フィールドをフィルターで除外し、すべてのURLをダウンロードします。
curl mysite/api.json | env `json-get-to-env X-AUTH-TOKEN`;curl -H X-AUTH-TOKEN $X-AUTH-TOKEN mysite/api/list.json | json-filter --field 'author' --rmatch 'R.{1,2}dal\d*' | json-get --field 'url' | xargs wget
find -lsの出力を解析し、サイズフィールドでソートし、配列から要素を10から20に切り取り、csvに出力します。
find . -ls | ls2josn | json-sort --field 'size' | json-slice [10:20] | json2csv
用語
入力
主なタスクは、乱雑な出力からjson-candyを作成することです。 重要:間違った入力を処理するオプションがあります:a)無視、b)エラーでパイプを停止します。
例:
ジェネリック:
- line2json-通常の出力を文字列の配列に変換します。文字列は文字列と一致します(行から文字列へ)。
- words2json-同様に、しかし言葉による。
- csv2json-cvsをオブジェクトに変換し、指定した要素にキーを割り当てることができます。
- lineparse2json-文字列をオブジェクトに変換し、指定された文字で除算します。 awk -Fを思い出させる: '{print $ 1、$ 2}'、
アプリ固有:
- ls2json(lsを選択するか、ls出力を取得できます)、オブジェクトの配列として構造化します。各オブジェクトは、フィールドの束を持つファイルです。 たぶんlsよりも多くの可能性があります(lsattrの通常および拡張属性、iノードに関するすべての情報、作成日など)
- ps2json-同様に、プロセスリスト別
- lsof2json-ファイルを使用するアプリケーションを記述するオブジェクトのリスト。
- openfiles2json-アプリケーションによって開かれたfdのリスト(/ proc / PID / fd)。ビルトインフィルタリング(「files only」、「ignore / dev / null」など)。 ネットワークソケット上のオブジェクトでは、すべての情報がすぐに添付されます-ポート/ IP。
- iptables2json-現在のiptables設定をjson形式で出力します
プライベートで促されるように、mysql-jsonはこの考えに完全に適合します。 SQLからの出力でバイナリを実行しますか? 簡単です。
ファイル固有:
ファイルを読み取り、jsonで出力します。
- syslog2json
- ini2json
- conf.d2json
- sysv2json、upstart2json
ネイティブJSON変換
最もおいしいのは、ネイティブのjson操作です。 同様に、「jsonではない」-「無視」/「停止」という処理オプションが必要です。
- json-filter-指定された基準に従ってオブジェクト/配列をフィルタリングします。
- json-join-2つのjson'ovのいずれかを指定されたメソッドにします。
- json-sort-指定されたフィールドでオブジェクトの配列をソートします
- json-slice-配列からピースを切り取ります
- json-arr-get-配列から要素を返します
- json-obj-get-指定されたオブジェクトの指定されたフィールドを返します
- json-obj-add-オブジェクトを追加します
- json-obj-del-オブジェクトを削除します
- json-obj-to-arr-キーまたはオブジェクトの特定のフィールドを配列として出力します
- json-arr-to-obj-配列を、指定された属性に従ってキーを形成するオブジェクトに変換します。
- json-uniq-配列内の重複する要素を削除する(または重複する要素のみを出力する)
(好みとニーズに追加)
出力
jsonを人間が読める形式で提供します。
- json2fullpath-jsonをkey1.key2 [3] .key4 = "foobar"の形式の文字列表記に変換します
- json2csv
- json2lines-オブジェクト内にある場合、行ごとに要素ごとに配列を出力します-行上でスペースで区切ります。
- json2keys-オブジェクトキーを印刷
- json2values-オブジェクト値のみを出力します
イテレータ
実際、jsonのxargs拡張機能:
- json-keys-iterate-各キーに対して指定されたコマンドを実行します
- json-values-iterate-各キーに対して指定されたコマンドを実行します
- json-iterate-各要素に対して指定されたコマンドを実行する
難しさ
もちろん、このような方法で任意のjsonを処理する問題を解決することは不可能です-あまりにも「構造化されていない」ことが判明する場合があります。 しかし、第一に、入力はjsonを予測可能に見せ、第二に、jsonの処理は既存のシェルの「要素がシェル内でスペースで区切られている」などの処理よりもさらに予測可能です。
実装
私は自分でそれを書きますが、何が必要なのか分からず、何かに十分な時間がありません。 プログラマーではありません。 この記事の秘密のアイデアは、「誰かが私のために書く」というものですが、これが見つからなければ、少なくとも自分でやり遂げる動機を備えたプログラム記事があります。
誰かがこれに取り組む準備ができているなら、私は非常に感謝します。 そうでない場合は、fig pythonを見つけます。アイデアや提案は大歓迎です。
更新:人々は少し動いたようです。 コミットはここで歓迎されます:
github.com/amarao/json4shell 。 使用できるかどうかはまだわかりません。 十分な火薬がありますか-私も知りません。