【问题标题】:Converting PascalCase string to kebab-case in bash without sed在没有sed的bash中将PascalCase字符串转换为kebab-case
【发布时间】:2021-11-15 06:36:27
【问题描述】:

我有这个工作 bash one-liner,它使用 sed 将 PascalCase 转换为 kebab-case:

foo="TestPascalCaseString"
echo $foo | sed -r 's/([a-z0-9])([A-Z])/\1-\2/g' | tr '[:upper:]' '[:lower:]'
output: test-pascal-case-string

但是,它用于需要在常见 Linux 发行版、Windows 上的 WSL 以及新旧版本的 macOS 之间移植的脚本。

在旧版本的 macOS 上,脚本失败并显示:

sed: illegal option -- r

我已经为任何 macOS 版本的用户解决了这个问题,方法是先让他们brew install gsed,然后让脚本使用gsed 而不是sed。这可行,但是 Linux 用户没有 gsed 二进制文件,因此他们需要将脚本改回使用 sed

所以我尝试使用纯 bash 解决方案或任何其他在所有平台上一致工作的工具重新创建它,以消除对必备工具安装或脚本修改的需要。

我已经尝试过 bash 参数替换:

foo="TestPascalCaseString"
echo ${foo//[A-Z]/-}
output: -est-ascal-ase-tring

用连字符替换大写字母,但我不知道如何保留它正在替换的大写字符。

【问题讨论】:

  • 你不想使用sed 太糟糕了,因为重写它以在所有平台上工作都是微不足道的:sed 's/\([a-z0-9]\)\([A-Z]\)/\1-\2/g'
  • @thatotherguy:我建议添加; s/\(.*\)/\L\1/,但我不知道它是否适用于所有平台。
  • @thatotherguy 谢谢,我已经确认 's/\([a-z0-9]\)\([A-Z]\)/\1-\2/g' 在我能够测试的所有平台(macOS 11 和 10.15,ubuntu 18.04 和 20.04)上都可以在没有 -r 标志的情况下工作,我会采用这个解决方案。我赞成您的评论,但我应该:a) 重写问题以声明我 am 可以使用不需要 -r 标志的 sed 解决方案,然后让您回答题?或者 b) 保留问题原样,以防有人发布可能对未来访客有帮助的非sed 解决方案?
  • 您可以接受最初发布的问题的答案
  • @Cyrus \L 在替换中是一个 GNU sed 扩展。

标签: string bash macos sed


【解决方案1】:

使用循环、正则表达式和 bash 版本 >= 3.0:

foo="TestPascalCaseString"
while [[ "$foo" =~ (.*[a-z0-9])([A-Z].*) ]] && foo="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}"; do
  :  # do nothing
done
echo "${foo,,}"

输出:

测试帕斯卡案例字符串

【讨论】:

  • while 循环用于替换sed 命令,因此我将其标记为正确答案。但是,在使用 bash (GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)) 运行脚本的 macOS 11.5 上,我得到了 ${foo,,}: bad substitution,所以我用 echo $foo | tr '[:upper:]' '[:lower:]' 替换了那个替换,这样就可以了。
  • 是的,我的错,我后来添加了,,bash 仅在 4.0 版本中获得该功能。
【解决方案2】:

使用 perl(我 99% 肯定 OS X 仍然附带):

$perl -ne 'print lc s/[[:lower:]\d]\K[[:upper:]]/-$&/rg' <<<"TestPascalCaseString"
test-pascal-case-string

【讨论】:

    猜你喜欢
    • 2019-07-06
    • 1970-01-01
    • 2022-07-15
    • 2022-07-08
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多