
以下はいくつかのサンプルコードです。
{"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
-C
UTF-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文書の別の場所に格納されている場合は、関連要素が抽出されるように式.[]
の最初の文字を変更するだけです(を含む最後の例の式には明らかに異なる変更が必要です)。jq
map()
答え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"}