sedはパイプを介して最後の文字インスタンスを削除しますか?

sedはパイプを介して最後の文字インスタンスを削除しますか?

複数行変数に生成されたjson配列がありますが、[{"name":"a"},{"name":"b"},{"name":"c"},]型、改行、スペースに関係なく、のような最後のコンマを削除する必要があります。

私は答えを使用しようとしていますこのQ&Aしかし、ファイルの代わりに変数を入力として使用しています。

たとえば、sed バージョンは次のようになります。

echo "$json" | sed -n 'x;${s/,$//;p;x}; 2,$ p'

私は例と同じように試していますが、awk成功しませんでした。

パイプを使用して取得できる唯一の答えはPerlページの下にありますecho "$json" | perl -0777 -pi -e 's/(.*),(.*?)/\1\2/s'

sed私は代わりにperl以下を使用したいと思います。地域設定forはperl私が管理しているコンピュータに常に設定されているわけではありません。

パイプ操作のためにsedコマンドをどのように変更しますか?

答え1

あなたが取った(素晴らしいbtw)答えは、2行目の変更にのみ適用されます。

1行だけで@I_GNU_it_all_alongが次のよう,]に置き換えるのははるかに簡単です]

echo "$json" | sed 's/,]/]/'

または、GNUの一般的なソリューションを使用してファイルの最後の文字インスタンスを削除しますsed

echo "$json" | sed -z 's/\(.*\),/\1/'

それは何をしますか?この-zオプションは、sed1行ずつ処理せずにバッファ全体を一度に処理するように指示するため、バッファの最後のコンマだけを置き換えることができます。

残念ながら、最初のカンマ(s/,//)または42番目のカンマ(s/,//42)は簡単に削除できますが、最後のカンマは削除できません(同様の操作は実装されていませs/,//$ん)。

したがって、私たちは「欲」を活用します*.*できるだけ多くの文字が一致するため、.*,最後のカンマまでのすべての文字が一致します。ただし、最後のカンマのみを削除したいので、他のすべての項目をで囲み、交換\(\)時にその部分をとして再利用できます\1

-zそのオプションがない場合は、sedバッファ内のすべての行を手動で収集する必要があります。

echo "$json" | sed 'H;1h;$!d;x;s/\(.*\),/\1/'

答え2

これはJSON関連の問題です。最後の配列エントリの後にカンマが続くと、,JSONバリデータはそのエントリと呼ばれるエラーを生成しますExpected another array element at line ...

努力するアッ解決策:

例jsonファイルinput.json(無効):

[
  {
    "name": "a"
  },
  {
    "name": "b",
    "keys": [
        1,2,3,
    ]
  },
  {
    "name": "c"
  },
]

awk -v RS= '{ gsub(/,[[:space:]]*]/, "\n]", $0) }1' input.json | jq '.'

出力(パイプ)ジャック):

[
  {
    "name": "a"
  },
  {
    "name": "b",
    "keys": [
      1,
      2,
      3
    ]
  },
  {
    "name": "c"
  }
]

答え3

,]インスタンスをに置き換えるとどうなりますか]

echo "$json" | sed 's/,]/]/'

関連情報