2

これを置き換えたい:

          }
      ]
  }
  {
      "commits":[

と:

          },

で使用可能な任意のコマンドを使用しbashます。

上記のテキストは、(ファイルからではなく)スクリプト自体から解析されています。bash「入力」はgit log、出力を噛み砕いてファイルに吐き出す 4 つの異なるパイプ コマンドによって解析される内容です。配管は次のようになります。

git log (...) | paste (...) | tail (...) | awk (...) > output.file

これまでの私の戦略は、追加のパイプと、次のようなamulti-line patternを aに置き換えるコマンドを追加することでした。single-line pattern

git log (...) | paste (...) | tail (...) | awk (...) | 'replace-multiline' (...) > output.file

つまり、replace-multilineまだ正しいコマンドを見つけることができていません。多分あなたは私を助けることができますか?;)

私が試したこと

awksedgrepさらにはさまざまなスピンを試して3日間使用しましperlた(複数行の検索と置換の課題を解決すると主張したもの)。それらのどれも私のコンテキストでは機能しませんでした。私はこれらのコマンドのどれにも精通していないので、暗闇の中で突っ込んできました. ポインタをいただければ幸いです。

バックグラウンド

有効な出力にbash出力するスクリプトに取り組んでいます( project at github )。スクリプトがリポジトリのルートから実行されると問題なく動作しますが、すべてのリポジトリを含むディレクトリから実行されるように拡張したいので、すべてのリポジトリを 1 回の呼び出しで形式で出力します。git logJSONgit logJSON

親ディレクトリに移動され、すべてのサブディレクトリ (gitリポジトリ) で実行されるように作成されたスクリプトは、以下の出力を返します (スクリプトは、リポジトリ名を各オブジェクト アイテム内のプロパティとして出力するようにも作成されています)。

現在の出力:

  {
      "commits":[
          {
              "repository":"repo1",
              "commit_nr":"1",
              /* ... */
          },
          {
              "repository":"repo1",
              "commit_nr":"2",
              /* ... */
          },
          {
              "repository":"repo1",
              "commit_nr":"3",
              /* ... */
          }
      ]
  }
  {
      "commits":[
          {
              "repository":"repo2",
              "commit_nr":"1",
              /* ... */
          },
          {
              "repository":"repo2",
              "commit_nr":"2",
              /* ... */
          },
          {
              "repository":"repo2",
              "commit_nr":"3",
              /* ... */
          }
      ]
  }
  {
      "commits":[
          {
              "repository":"repo3",
              "commit_nr":"1",
              /* ... */
          },
          {
              "repository":"repo3",
              "commit_nr":"2",
              /* ... */
          },
          {
              "repository":"repo3",
              "commit_nr":"3",
              /* ... */
          }
      ]
  }

必要な出力:

  {
      "commits":[
          {
              "repository":"repo1",
              "commit_nr":"1",
              /* ... */
          },
          {
              "repository":"repo1",
              "commit_nr":"2",
              /* ... */
          },
          {
              "repository":"repo1",
              "commit_nr":"3",
              /* ... */
          },
          {
              "repository":"repo2",
              "commit_nr":"1",
              /* ... */
          },
          {
              "repository":"repo2",
              "commit_nr":"2",
              /* ... */
          },
          {
              "repository":"repo2",
              "commit_nr":"3",
              /* ... */
          },
          {
              "repository":"repo3",
              "commit_nr":"1",
              /* ... */
          },
          {
              "repository":"repo3",
              "commit_nr":"2",
              /* ... */
          },
          {
              "repository":"repo3",
              "commit_nr":"3",
              /* ... */
          }
      ]
  }
4

3 に答える 3

2

これには perl を使用します。

$echo "          {
              "repository":"repo2",
              "commit_nr":"3",
              /* ... */
          }
      ]
  }
  {
      "commits":[
          {
              "repository":"repo3",
              "commit_nr":"1",
              /* ... */
          }," | perl -pn -e "BEGIN{undef $/;} s/\}\s*\]\s*\}\s*\{\s*commits:\[/},/g"

収量

          {
              repository:repo2,
              commit_nr:3,
              /* ... */
          },
          {
              repository:repo3,
              commit_nr:1,
              /* ... */
          },

注意:単語\"の前後に追加する必要がある場合があります(これは であり、コピペでエスケープされないため消えます)commitecho"

于 2013-03-15T19:55:44.357 に答える
0

あなたが欲しいのはperlのフリップフロップ演算子のように聞こえますが、あなたが持っているのは(現在の出力から収集できるものから)適切にフォーマットされた一連のperlハッシュであるため、古いハッシュを組み合わせて新しいハッシュを作成するだけです好きな構造で。この perl スクリプトは、パイプラインの最後に位置し、データを変更する可能性があります。

于 2013-03-15T19:56:40.927 に答える
0

sed だけを使用する場合は、サンプル入力で以下が機能します。

sed -En '1h;1!H;${;g;s/( +)}\n +\]\n + }\n +{\n + "commits":\[\n/\1};/g;p;}'
于 2013-03-15T20:06:28.890 に答える