仅当子字符串的长度超过3个字符时,才将其首字符大写

时间:2019-01-17 02:06:43

标签: sed tr

我需要转换此字符串:

  

我的名字是用户,不在这里。

收件人:

  

我的名字这里的用户不是那里

详细信息是,我需要用超过3个字符将任何单词的第一个字符串起来。只是它。我正在尝试使用以下命令失败:

echo $FOO | tr '[:upper:]' '[:lower:]' | sed -e "s/\b\(.\)/\u\1/g"

其他所有内容都应小写。

4 个答案:

答案 0 :(得分:2)

使用 GNU sed(和bash):

F="my name is user from here not there."
sed -E 's/^./\u&/;s/([[:space:]])([[:alpha:]]{4})/\1\u\2/g' \ 
    <<< "${F,,}"

或:

sed -E 's/^./\u&/;s/(\s)(\w{4})/\1\u\2/g' <<< "${F,,}"

输出:

My Name is User From Here not There.

注意:

"${F,,}"bash case modification parameter expansion,它返回$F的小写版本,它成为sed的输入。

GNU sed为常见的 regex 字符类提供了一些有用的synonyms and abbreviations。字符类[a-zA-Z0-9_]可以缩写为[[:alpha:]_],或更简单的\w

尽管\u看起来像是 regex 的缩写,但事实并非如此。它是"special sequence",仅用于s ubstitute 命令替换文本中-\u表示“将下一个字符转为大写”

&是指s ubstitute 命令中第一个 regexp 匹配的内容。比较以下内容:

sed 's/./&/'          <<< foo  # outputs "f"
sed 's/./&/g'         <<< foo  # outputs "foo"
sed 's/./&&&&/g'      <<< foo  # outputs "ffffoooooooo"
sed 's/./\u&&&\u&/g'  <<< foo  # outputs "FffFOooOOooO"
sed 's/.*/&&&&/'      <<< foo  # outputs "foofoofoofoo"

有关更多详细信息,请参见GNU sed info pages

答案 1 :(得分:2)

这可能对您有用(GNU sed):

sed -E 's/^\w+|\b\w{4,}\b/\u&/g' file

如果单词出现在以单词或任何单词(长度为4个或更多字符)开头的行中,则该单词的首字母大写

答案 2 :(得分:1)

请您尝试以下。

echo "my name is user from here not there." |
awk '{for(i=1;i<=NF;i++)
    if(length($i)>3){$i=toupper(substr($i,1,1)) substr($i,2)}}
    1'

结果:

my Name is User From Here not There.

答案 3 :(得分:1)

tr并不是这项工作的正确工具;它根本不了解上下文。

sed的某些变体具有Perl或vi regex扩展名,但实际上也无法通过sed来解决。

抢救Perl:

bash$ foo="my name is user from here not there."

bash$ echo "$foo" | perl -pe 's/\w{4,}/\u$&/g'
my Name is User From Here not There.

这确实是您实际要的,但不是您想要的。也许添加条件以分别大写输入的第一个单词……或切换到Lingua::EN::Titlecase之类的库。

还请注意do not use upper case for our private variables(由于大写变量保留供系统使用)和always quote our shell strings.