在bash 3.2中使用字符串的最简单方法是什么?

时间:2015-10-25 00:17:44

标签: macos bash shell

例如:var=dogecho $var输出为 dog 大写$var 预期输出

尝试了多种方式但却没有获得预期的输出。 一些尝试:

echo $var | sed "s/[a-z]\&[:upper:]//"  #dog
echo $var | sed "s/([a-z])/[:upper:]/"  #dog

4 个答案:

答案 0 :(得分:7)

<强> TL; DR:

  • macOS,支持Unicode, 跨平台,但仅限ASCII,以及背景信息

    • 请参阅下面的tr解决方案。
  • GNU 实用程序,支持Unicode (Linux:预装; macOS:可通过Homebrew安装):

    • sed 's/^./\u&/' <<<'dog' # -> 'Dog'
      • macOS:使用brew install gnu-sed安装后,使用gsed代替sed
    • awk替代方案:见dev-null's answer
      • macOS:使用brew install gawk安装后,使用gawk代替awk
  • 跨平台,支持Unicode

  • Bash 4+,支持Unicode ,在macOS上你也可以用Homebrew安装:

    • echo "${var^}"

尝试

var='dog'
echo "$(tr '[:lower:]' '[:upper:]' <<<"${var:0:1}")${var:1}" # -> 'Dog'
  • tr '[:lower:]' '[:upper:]' <<<"${var:0:1}"$var${var:0:1})中提取第一个字符,并使用tr将其翻译为大写字母。

  • ${var:1}返回$var值中第二个字符的所有内容。

请注意,此解决方案支持Unicode [1] ,与macOS awkPython 2.x solutions 更新不同:@idjaw已修复带有.decode('utf-8') 的Python 2.x解决方案,可能也比它们稍快(tr的重量轻于awkpython

[1]这适用于macOS附带的 BSD tr版本。相比之下, GNU tr 正确地处理非ASCII字符 - 根据维基百科John1024 "Most versions of tr, including GNU tr and classic Unix tr, operate on single-byte characters and are not Unicode compliant."注释

至于您尝试sed解决方案

使用macOS(BSD)sed,我不知道任何子串 - 操作功能。

如果你有 GNU sed - 你可以通过Homebrew安装 - 你可以使用以下内容:

sed 's/^./\u&/' <<<'dog' # -> 'Dog'

\u告诉GNU Sed将以下字母大写。可悲的是,你不能用macOS的Sed做到这一点。

[:upper:]仅作为匹配的字符类工作,它从不执行转换,这就是您的命令不起作用的原因。 唯一的例外是tr,您可以将[:upper:][:lower:]配对以实现转换,就像我上面的解决方案一样。

预览 Bash 4 +解决方案

var='dog'; echo "${var^}"

答案 1 :(得分:4)

如果这是一个选项,您可以使用Python:

在得到不同人的意见后(感谢所有人),这似乎是一个很好的工作解决方案,符合@ PM2Ring提出的第一个字母的OP请求:

仅针对第一个字符提出的最佳解决方案

bash-3.2$ var="it's an öyster's life"
bash-3.2$ python -c "import sys;print sys.argv[1].decode('utf8').capitalize()" "$var"
It's an öyster's life

以下解决方案尝试将字符串中所有单词首字母大写:

以下解决方案有一些缺点:

bash-3.2$ python -c "print raw_input().decode('utf-8').title()" <<<"it's an öyster's life" 
It'S An Öyster'S Life

使用变量的简单解决方案:

bash-3.2$ var='dog is dog'
bash-3.2$ python -c "print raw_input().decode('utf-8').title()" <<<"$var"
Dog Is Dog

从本答案的评论中可以看出(感谢所有输入),重要的是要注意使用它的局限性,特别是使用OSX本机Python语言2.7。

示例1 :(感谢@ john1024&amp; @ dev-null)

引用问题。

使用处理以下字符串示例所需的引号的小修改

var="it's a dog's life"
bash-3.2$ python -c "print '$var'.title()"
It'S A Dog'S Life

对我的解决方案不起作用的其他示例:var="hello ''' world"

示例2 :(感谢@ mklement0)

Unicode问题

bash-3.2$ var='öyster'
bash-3.2$ python -c "print '$var'.title()"
öYster

请注意,它将第二个字母大写,这是第一个ascii字符,标题方法将按照Python2中的预期方式大写。

可以对解决方案进行以下修改以帮助解决unicode字符:

bash-3.2$ var='öyster'
python -c "print '$var'.decode('utf-8').title()" 
Öyster

最后,当从下面的讨论中将解决方案放在一起时,这就是它最终组合在一起的方式:

python -c "print raw_input().decode('utf-8').title()" <<<"it's an öyster's life" 

答案 2 :(得分:3)

var="hello world"
echo "$var" | awk '{print toupper(substr($0, 1, 1)) substr($0, 2)}' # Hello world

如果你想把每个单词大写:

var="hello world"
echo "$var" | awk 'BEGIN{RS = " "};{printf("%s ", toupper(substr($0, 1, 1)) substr($0, 2))}' # Hello World

答案 3 :(得分:2)

如果您想要识别unicode,请考虑使用perl:

$ perl -lne 'use open qw(:std :utf8); print ucfirst' <<< 'dog'
Dog
$ perl -lne 'use open qw(:std :utf8); print ucfirst' <<< 'élan'
Élan

正如评论中所指出的那样:

$ perl -C -lne 'print ucfirst' <<< 'élan'
Élan