Bashで大文字に文字列を追加する方法

Bashで大文字に文字列を追加する方法

以下はいくつかのサンプルコードです。

{"key_code":"a"},
{"key_code":"B"},
{"key_code":"c"},
{"key_code":"D"}

これが私がしたいことです:

{"key_code":"a"},
{"key_code":"b","modifiers":"left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers":"left_shift"}

私のIDEでは大文字と小文字を区別して検索し、"([A-Z])"次に置き換えることができますが、"\L$1", "modifiers": "left_shift"bashスクリプトでは使用できないようです。

\L私はMac OS Xを使用しており、これが問題を引き起こしているようです。

私はいくつかのバージョンを試しました:

sed -i "" 's/"([A-Z])"/"\L$1","modifiers": "left_shift"/g' file

そして

sed -i "" "s/\"([A-Z])\"/\"\L$1\",\"modifiers\": \"left_shift\"/g" file

しかし幸運はありません。あちこち歩き回ろうと努力したけれど不明awkそうです…

答え1

Macosで見つかったFreeBSDは代替AFAIKをsedサポートしていません\L。いつでも以下を使用できますperl

perl -pi -e 's/"\p{Lu}"/\L$&,"modifiers":"left_shift"/g' file

-CUTF-8でエンコードされた非ASCII大文字(たとえばÊÇなどΞ)も処理するオプションが追加されました。

答え2

表示するJSONオブジェクトが以下のように最上位配列の一部であるとします(キーと値の外側の空白文字は関係ありません)。

[
  {
    "key_code": "a"
  },
  {
    "key_code": "B"
  },
  {
    "key_code": "c"
  },
  {
    "key_code": "D"
  }
]

その後、各値が大文字かどうかをテストし、大文字のkey_code場合はmodifiersオブジェクトに追加できます。

jq '(.[] | select(.key_code | test("[[:upper:]]"))) += { "modifiers": "left_shift" }' file

または(ただし、やや短い)、

jq '(.[] | select(.key_code | test("[[:upper:]]"))).modifiers |= "left_shift"' file

map()または最上位配列で使用します。

jq 'map(select(.key_code | test("[[:upper:]]")).modifiers |= "left_shift")' file

質問に与えられた入力に基づいて、次の出力が生成されます。

[
  {
    "key_code": "a"
  },
  {
    "key_code": "B",
    "modifiers": "left_shift"
  },
  {
    "key_code": "c"
  },
  {
    "key_code": "D",
    "modifiers": "left_shift"
  }
]

配列がより大きなJSON文書の別の場所に格納されている場合は、関連要素が抽出されるように式.[]の最初の文字を変更するだけです(を含む最後の例の式には明らかに異なる変更が必要です)。jqmap()

答え3

入力が毎回まったく同じに見える場合は、これで十分です。

awk '{if(/:"[A-Z]"/) sub(/"}/, "\",\"modifiers\":\"left_shift\"}"); print tolower($0) }' inputfile > outputfile

別のオプションは次のとおりです。

sed 's/"[A-Z]"/&,"modifiers": "left_shift"/g' inputfile | tr '[[:upper:]]' '[[:lower:]]' > outputfile

Macではテストできませんが、動作するのに十分一般的なようです。

tolower($0)そして、コマンドはtrすべてすべてを小文字で返すので、望むかもしれないしそうでないかもしれないので、それほど柔軟なオプションではありません。

答え4

GNU sedの使用(まだない場合はMacにインストール):

$ sed 's/"[A-Z]"/\L&,"modifiers":"left_shift"/' file
{"key_code":"a"},
{"key_code":"b","modifiers":"left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers":"left_shift"}

\1代わりに逆参照を使用して角括弧をエスケープしてリテラルではなくグループ境界をキャプチャする場合、$1既存のコードはGNU sedでも機能します。例:

$ sed 's/"\([A-Z]\)"/"\L\1","modifiers": "left_shift"/g' file
{"key_code":"a"},
{"key_code":"b","modifiers": "left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers": "left_shift"}

または、デフォルトのBREの代わりにEREを有効にします。

$ sed -E 's/"([A-Z])"/"\L\1","modifiers": "left_shift"/g' file
{"key_code":"a"},
{"key_code":"b","modifiers": "left_shift"},
{"key_code":"c"},
{"key_code":"d","modifiers": "left_shift"}

関連情報