如何使用 tr 将任何文本更改为正确大小写和句子大小写?

7 text-processing tr

根据https://caseconverter.com/

\n\n
\n

\xe2\x80\x9cUpper Case\xe2\x80\x9d 将所有字母转换成这样的大写字母。

\n\n

\xe2\x80\x9cLower Case\xe2\x80\x9d 将所有字母转换为小写字母,如下所示。

\n\n

\xe2\x80\x9c正确的情况\xe2\x80\x9d 转换文本,因此每个单词的第一个\n字母都大写,如下所示

\n\n

\xe2\x80\x9c句格\xe2\x80\x9d。这会将每个句子的第一个字母大写,\n 并将文本的其余部分转换为小写。因此,每个句号后的第一个字母\n 会自动转换为大写\n 字母。

\n
\n\n

前两个可以通过命令轻松完成tr

\n\n
user@linux:~$ tr [:lower:] [:upper:] <<< eXaMPLe\nEXAMPLE\nuser@linux:~$ \n\nuser@linux:~$ tr [:upper:] [:lower:] <<< eXaMPLe\nexample\nuser@linux:~$ \n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
user@linux:~$ tr [a-z] [A-Z] <<< eXaMPLe\nEXAMPLE\nuser@linux:~$ \n\nuser@linux:~$ tr [A-Z] [a-z] <<< eXaMPLe\nexample\nuser@linux:~$ \n
Run Code Online (Sandbox Code Playgroud)\n\n

最后两个“正确案例”和“句子案例”怎么样?

\n\n

是否可以?

\n\n

如果是,请告诉我。

\n\n

如果不是,还有什么替代方案?

\n

Sté*_*las 5

请注意,除非您的 shellfish不支持通配符[...],否则您应该引用这些[:lower:], [A-Z],否则 shell 可能会将它们扩展到当前目录中的匹配文件列表(如果不匹配则报告错误):

\n
tr '[:lower:]' '[:upper:]'\n
Run Code Online (Sandbox Code Playgroud)\n

其他注意事项:

\n
    \n
  • GNU 实现tr仅支持单字节字符,因此在 UTF-8 语言环境中,它只会大写英文字母,不带变音符号。
  • \n
  • tr '[A-Z]' '[a-z]'很好,但你也可以简单地这样做tr A-Z a-z(在 POSIX 兼容的实现中)。ABCDEFGHIJKLMNOPQRSTUVWXYZ但是,它只能保证仅在 C/POSIX 语言环境中匹配。
  • \n
\n

要将每个单词的第一个字母大写,使用 的 GNU 实现sed,您可以执行以下操作:

\n
sed -E "s/[[:alnum:]_'-]+/\\u&/g"\n
Run Code Online (Sandbox Code Playgroud)\n

我们包括', ,-_不包括其他标点符号,以便foo-bar2baz,foo变成Foo-bar2baz,Foo

\n

这适用于多字节字符,但通常不适用于组合字符,因为大多数语言环境不会将它们视为alnum

\n
$ echo $'ste\\u0301phane' | sed -E "s/[[:alnum:]_']+/\\u&/g"\nSt\xc3\xa9Phane\n
Run Code Online (Sandbox Code Playgroud)\n

要考虑这些,您可以切换到perl,其中这些可以与 匹配\\pM

\n
$ echo $'ste\\u0301phane chazelas' | perl -Mopen=locale -pe 's/[\\w\\pM'\\''-]+/\\u$&/g'\nSt\xc3\xa9phane Chazelas\n
Run Code Online (Sandbox Code Playgroud)\n

另请注意,这会将\xef\xac\x81rst(其第一个字符是连字 \xef\xac\x81 字符)转换为FIrst。使用ucfirst()而不是uc()/\\u可以避免这种情况:

\n
$ echo '\xef\xac\x81rst second' | perl -Mopen=locale -pe 's/[\\w\\pM'\\''-]+/ucfirst$&/ge'\nFirst Second\n
Run Code Online (Sandbox Code Playgroud)\n

对于句子大写,这是相当棘手的,你必须将文本开头或句子定界符(如., ?, \xe2\x80\xa6\xe2\x80\xa6 )或句子介绍符(\xc2\xbf, \xc2\xa1)之后的第一个字母大写,允许任意数量的之间有空格,还有(, [, ", \xe2\x80\xb6, \xe2\x80\xb7, \xc2\xab\xe2\x80\xa6) 之类的东西。根据您想要支持的语言,您可能需要考虑更多。

\n

你可以用类似的东西来做到这一点perl

\n
perl -0777 -C -pe 's/(^|[.!?\xe2\x80\xa6\xe2\x81\x87\xe2\x81\x88\xe2\x81\x89\xc2\xbf\xc2\xa1])[\\s([{"`\xe2\x80\xb6\xe2\x80\xb7\xc2\xab]*\\K\\p{Ll}/ucfirst$&/ge'\n
Run Code Online (Sandbox Code Playgroud)\n

这里假设使用 UTF-8 语言环境和输入,并且仅涵盖其中的一些情况。

\n

无论如何,这不是一个人就能完成的事情,tr因为每个tr字符都要音译,不能只音译某些字符。

\n


use*_*170 2

不,单独行动是不可能的trtr不理解完成这项工作所需的单词或句子。

作为替代方案,您可以尝试 Perl 及其强大的模式引擎:

$ perl -pe 's/\b[\p{L}\p{Pd}]+/ucfirst lc $&/ge' <<< 'A HEART-SHAPED BOX'
A Heart-shaped Box
$ perl -pe 's/\p{L}.*?[.?!]/ucfirst lc $&/ge' <<< 'for sale. baby shoes. never worn.'
For sale. Baby shoes. Never worn.
Run Code Online (Sandbox Code Playgroud)

然而,上面的解决方案是一个快速而肮脏的解决方案,并没有涵盖所有可能的情况,并且需要进行调整(非拉丁字母和非 ASCII 拉丁字母、依赖于语言环境的情况、文章不大写) 、句子中的专有名词大写等)。话又说回来,两者都做不到tr