在 BASH 中将电子邮件 ID 中的所有第一个字符转换为大写

Abh*_*avK 4 bash

我需要在脚本中接受电子邮件 ID 和全名,如果未提供全名,我需要从电子邮件 ID 生成名称。像这样的东西:

Case 1:
EmailID: user.name@domainname.com
Full Name: User Name
Case 2:
EmailID: user.name2@domainname.com
Full Name: User Name2
Case 3:
EmailID: this.is.a.very.long.email.id@domainname.com
Full Name: This Is A Very Long Email Id
Run Code Online (Sandbox Code Playgroud)

这我已经能够使用以下步骤实现:

EMAIL_ADDRESS="$1"
ID=(`echo $EMAIL_ADDRESS | cut -d'@' -f1| tr '.' ' '`)
NEW_ID=()
NUM=0
for IN_VAL in ${ID[@]}
do
    NEW_ID[$NUM]="`echo ${IN_VAL^}`"
    NUM=$((++NUM))
done
echo "${NEW_ID[@]}"
Run Code Online (Sandbox Code Playgroud)

我在 BASH 版本 4.1.2

我认为必须有更好的方法来实现这一目标。此外,我已经看到了一个问题,因为我假设字段分隔符将是点 (.) 字符,而不是像下划线 (_) 或连字符 (-) 或其他任何东西。如果有更好的方法来做到这一点,请告诉我。谢谢。

Mic*_*mer 9

您实际上可以完全在 Bash 中执行此操作,无需任何外部命令,使用分参数扩展。它甚至相当短:

EMAIL_ADDRESS=this.is.a.very-long_email.id@domainname.com
USER=${EMAIL_ADDRESS%@*}
WORDS=( $(IFS=._- ; printf '%s ' $USER) )
echo "${WORDS[@]^}"
Run Code Online (Sandbox Code Playgroud)

我将逐行执行此操作:

USER=${EMAIL_ADDRESS%@*}
Run Code Online (Sandbox Code Playgroud)

这会将USER变量设置为最后EMAIL_ADDRESS不匹配的部分@*- 即删除域名并只留下地址的用户部分。

WORDS=( $(IFS=._- ; printf '%s ' $USER) )
Run Code Online (Sandbox Code Playgroud)

这将创建一个初始化数组 WORDS。初始值由命令替换$(...)的结果给出。

命令替换在子 shell 中运行,因此我们可以安全地更改变量的值,而不会影响它们在主 shell 中的值。这包括IFS,在分期间用作导致新词开始的字符组。每个人._以及-将形成一个单词边界,如果你愿意,你可以在那里添加新的角色。

改变后IFS我们printf用来打印出$USER已经拆分的单词,比echo.

echo "${WORDS[@]^}"
Run Code Online (Sandbox Code Playgroud)

最后,我们打印出结果。的[@]是阵列扩展,你也知道,然后^ 执行上部壳体在单词的第一个字符的(严格地说,默认模式的第一匹配?)。

运行此脚本的最终结果是输出:

This Is A Very Long Email Id
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。


如果任何电子邮件地址包含 shell 元字符*?等,它们将被扩展为通配符。您可以将WORDS=行包在set -f/ 中set +f以避免这种情况,但还有另一种选择(由 Glenn Jackman 在评论中提供)。

IFS=._- read -r -a WORDS <<<"${EMAIL_ADDRESS%@*}"
echo "${WORDS[@]^}"
Run Code Online (Sandbox Code Playgroud)

这用于使用read -a分词结果填充数组,其余部分(压缩)与以前一样。我发现这比显式数组初始化更难阅读,但它是一个选项。

还值得注意的是,电子邮件地址可以严格地具有多种形式,包括其中包含空格、引号和括号字符的形式,并且这根本不涉及这些地址(也确实不可能这样做)您的问题说明)。


gle*_*man 7

使用 sed:

sed 's/@.*//; s/[-_.]/ /g; s/\<./\U&/g' <<END
user.name@domainname.com
user.name2@domainname.com
this.is.a.very.long.email.id@domainname.com
END
Run Code Online (Sandbox Code Playgroud)
User Name
User Name2
This Is A Very Long Email Id
Run Code Online (Sandbox Code Playgroud)

\U大写指令需要 GNU sed 。

https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-Command

扩展:

sed '
    s/@.*//        # remove @domain.name
    s/[-_.]/ /g    # translate dot,dash,underscore to spaces
    s/\<./\U&/g    # uppercase the first character of a word
                   # \< is a beginning-of-word marker
'
Run Code Online (Sandbox Code Playgroud)

一个高深莫测的 perl 单行:

perl -nE's/@.*//;say"@{[map{ucfirst}/(\w+)/g]}"' 
Run Code Online (Sandbox Code Playgroud)

由于 perl 的\w字符类快捷方式包含下划线,因此
this.is.a.very-long_email.id@domainname.com变为
This Is A Very Long_email Id