如何在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 脚本中使用它。

我使用的是 Mac OS X,所以我认为这\L给我带来了麻烦。

我尝试过几个版本:

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 上发现的FreeBSDsed不支持\L替换 AFAIK。您始终可以使用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,以便提取相关元素(最后一个示例表达式 with 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"}

或者启用 ERE 而不是默认的 BRE:

$ 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"}

相关内容