linux command to transform 'VW_ABCD_EF_GHIJ_KLM_…' into 'AbcdEfGhjKlm…'

huangapple go评论105阅读模式
英文:

linux command to transform 'VW_ABCD_EF_GHIJ_KLM_...' into 'AbcdEfGhjKlm...'

问题

I am trying to modify a string with the pattern 'VW_ABCD_EF_GHIJ_KLM_...' into 'AbcdEfGhjKlm...'.

For example "s=VW_ABCD_EF_GHIJ_KLM" must become "AbcdEfGhjKlm".

So far I got s=VW_ABCD_EF_GHIJ_KLM; echo "${s,,}" | sed -e 's/vw\(.*\)/\1/g' which produces "_abcd_ef_ghij_klm".

I think I would have to create a variant number of groups for (.*) and replace '[a-z]' for '[A-Z]' in every group, but I could not find how to do it.

英文:

I am trying to modify a string with the pattern 'VW_ABCD_EF_GHIJ_KLM_...' into 'AbcdEfGhjKlm...'

For example "s=VW_ABCD_EF_GHIJ_KLM" must become "AbcdEfGhjKlm".

So far I got s=VW_ABCD_EF_GHIJ_KLM; echo "${s,,}" | sed -e 's/vw\(.*\)/\1/g' which produces "_abcd_ef_ghij_klm".

I think I would have to create a variant number of groups for \(_.*\) and replace '_[a-z]' for '[A-Z]' in every group, but I could not find how to do it

答案1

得分: 2

对 OP 当前的代码进行扩展,以去除 _ 并将 _ 后面的字母大写:

$ s='VW_ABCD_EF_GHIJ_KLM'
$ sed -e 's/vw\(.*\)//g;s/_\(.\)/\U/g' <<< "${s,,}"
AbcdEfGhijKlm

在限制 VW 移除到字符串开头的情况下,可实现同等效果:

$ s='VW_ABCD_EF_GHIJ_KLM'
$ sed -E 's/^vw//g;s/_(.)/\U/g' <<< "${s,,}"
AbcdEfGhijKlm

注意: 假设每个 _ 后面跟着一个字母(如 OP 示例)。

英文:

Expanding on OP's current code to strip the _ and Uppercase the letter following the _:

$ s=&#39;VW_ABCD_EF_GHIJ_KLM&#39;
$ sed -e &#39;s/vw\(.*\)//g;s/_\(.\)/\U/g&#39; &lt;&lt;&lt; &quot;${s,,}&quot;
AbcdEfGhijKlm

One equivalent while limiting the VW removal to the start of the string:

$ s=&#39;VW_ABCD_EF_GHIJ_KLM&#39;
$ sed -E &#39;s/^vw//g;s/_(.)/\U/g&#39; &lt;&lt;&lt; &quot;${s,,}&quot;
AbcdEfGhijKlm

NOTE: assumes each _ is followed by a letter (as in OP's example)

答案2

得分: 2

A slightly different solution, without the initial ${s,,} processing:

$ s='VW_ABCD_EF_GHIJ_KLM'
$ echo "$s" | sed -E 's/^VW//; s/_([^_]+)/\L\u/g'
AbcdEfGhijKlm

\L\u\1 将使首字母大写,其余小写。

但如果输入不总是大写的:

$ s='Vw_ABcd_ef_GHIJ_KLM'
$ echo "$s" | sed -E 's/^vw(.*)/\L/I; s/_(.)/\u/g'
AbcdEfGhijKlm
英文:

A slightly different solution, without the initial ${s,,} processing:

$ s=&#39;VW_ABCD_EF_GHIJ_KLM&#39;
$ echo &quot;$s&quot; | sed -E &#39;s/^VW//; s/_([^_]+)/\L\u/g&#39;
AbcdEfGhijKlm

\L\u\1 will uppercase the first character and remaining are lowercased.

But if the input isn't always uppercase:

$ s=&#39;Vw_ABcd_ef_GHIJ_KLM&#39;
$ echo &quot;$s&quot; | sed -E &#39;s/^vw(.*)/\L/I; s/_(.)/\u/g&#39;
AbcdEfGhijKlm

答案3

得分: 1

以下是翻译好的部分:

这里有一个使用 perl 的版本,而不是依赖于 GNU sed 和非标准的 \u/等转义字符:

$ s=VW_ABCD_EF_GHIJ_KLM
$ perl -ne 'my @a = map ucfirst, split(/_/, lc); print @a[1..$#a]' <<<"$s"
AbcdEfGhijKlm

当然,perl 也支持 GNU sed 风格的正则表达式大小写转换:

$ perl -pe 's/^VW//; s/_([^_])([^_]*)/\u\L/g' <<<"$s"
AbcdEfGhijKlm

这两个变体,与 GNU sed 的方式不同,对字母进行了标题大小写转换,而不仅仅是简单的大写。对于ASCII字符来说是相同的,但如果你需要扩展到其他字符集,这可能会有所不同。

英文:

Here's a version that uses perl instead of depending on GNU sed and it's non-standard \u/etc. escapes:

$ s=VW_ABCD_EF_GHIJ_KLM
$ perl -ne &#39;my @a = map ucfirst, split(/_/, lc); print @a[1..$#a]&#39; &lt;&lt;&lt;&quot;$s&quot;
AbcdEfGhijKlm

Of course, perl also supports GNU sed-style case-transformation in a regular expression:

$ perl -pe &#39;s/^VW//; s/_([^_])([^_]*)/\u\L/g&#39; &lt;&lt;&lt;&quot;$s&quot;
AbcdEfGhijKlm

Both of these variants, unlike the GNU sed ones, do title casing of the letters, not simple upper casing. It's the same thing when it comes to ASCII characters, but if you ever have to expand to alphabets beyond that, it can make a difference.

huangapple
  • 本文由 发表于 2023年5月29日 22:52:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358325.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定