如何在OSX中使用sed将每个单词的首字母大写

时间:2015-08-12 14:56:33

标签: macos bash sed pipe capitalization

我正在尝试使用以下sed命令将字符串中每个单词的第一个字母大写,但它不起作用:

 echo "my string" | sed 's/\b\(.\)/\u\1/g'

输出:

 my string

我做错了什么?

谢谢

4 个答案:

答案 0 :(得分:4)

根据您的示例输入,这将适用于任何awk:

$ echo 'my string' | awk '{for (i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)} 1'
My String

如果那样做不是你真正想要的,那么编辑你的问题,以显示一些更真实的代表性样本输入和预期输出。

答案 1 :(得分:1)

这是一个适用于OSX的sed解决方案:

echo 'my string
ANOTHER STRING
tHiRd StRiNg' | sed -En '
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
:loop
h
s/^(.*[^a-zA-Z0-9])?([a-z]).*$/\2/
t next
b end
:next
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
G
s/^(.+)\n(.*[^a-zA-Z0-9])?[a-z](.*)$/\2\1\3/
t loop
:end
p
'

Output:
My String
Another String
Third String

sed命令的工作原理如下:

  1. sed输入一行,第一个y命令将所有大写字母转换为小写。
  2. 来自:loop到t循环的命令形成一个循环,执行一次     当前行中的每个单词,将每个单词的第一个字母大写。
  3. 当没有更多单词要为当前行大写时,p命令打印该行,sed输入下一行。
  4. 以下是循环的工作原理:

    1. h命令保存当前处于保持状态的线路 空间。
    2. 第一个s命令查找第一个字母的第一个字母 非大写字。如果找到这样的单词,则s命令保存 它是模式空间的第一个字母,而t命令分支到 :下一个标签。如果找不到这样的单词,则表明这一点 没有更多的词来大写,执行b命令 相反,分支到:end标签打印出来并完成 处理当前行。
    3. 如果找到需要大写的单词,则执行恢复 :next标签,y命令将第一个字母(现在位于模式空间中)从小写转换为大写。
    4. G命令附加当前的非转换版本 从保留空间到模式空间末尾的行。
    5. 第二个s命令重建当前行,将当前正在处理的单词的第一个字母替换为其大写版本。
    6. t命令分支到:loop标签以查找下一个单词 需要资本化。
    7. 执行速度测试表明,当前的sed方法的执行速度与Ed Morton提交的awk解决方案大致相同。

答案 2 :(得分:0)

已经解决了这个问题:Uppercasing First Letter of Words Using SED

我使用GNU sed获得了正确的行为,但没有使用OS X附带的标准BSD sed。我认为\ u&#34;正则表达式&#34;是一个GNU的东西。怎么样&#34;端口安装gsed&#34;?

编辑:如果您真的想要使用BSD sed,我不推荐(因为命令变得非常难看),那么您可以执行以下操作: sed -E "s:([^[:alnum:]_]|^)a:\1A:g; s:([^[:alnum:]_]|^)b:\1B:g; s:([^[:alnum:]_]|^)c:\1C:g; s:([^[:alnum:]_]|^)d:\1D:g; s:([^[:alnum:]_]|^)e:\1E:g; s:([^[:alnum:]_]|^)f:\1F:g; s:([^[:alnum:]_]|^)g:\1G:g; s:([^[:alnum:]_]|^)h:\1H:g; s:([^[:alnum:]_]|^)i:\1I:g; s:([^[:alnum:]_]|^)j:\1J:g; s:([^[:alnum:]_]|^)k:\1K:g; s:([^[:alnum:]_]|^)l:\1L:g; s:([^[:alnum:]_]|^)m:\1M:g; s:([^[:alnum:]_]|^)n:\1N:g; s:([^[:alnum:]_]|^)o:\1O:g; s:([^[:alnum:]_]|^)p:\1P:g; s:([^[:alnum:]_]|^)q:\1Q:g; s:([^[:alnum:]_]|^)r:\1R:g; s:([^[:alnum:]_]|^)s:\1S:g; s:([^[:alnum:]_]|^)t:\1T:g; s:([^[:alnum:]_]|^)u:\1U:g; s:([^[:alnum:]_]|^)v:\1V:g; s:([^[:alnum:]_]|^)w:\1W:g; s:([^[:alnum:]_]|^)x:\1X:g; s:([^[:alnum:]_]|^)y:\1Y:g; s:([^[:alnum:]_]|^)z:\1Z:g;"

答案 3 :(得分:-2)

尝试:

echo "my string" | sed -r 's/\b(.)/\u\1/g'