如何在 bash 中创建数字名称

art*_*rty 10 bash awk cut

我正在尝试编写一个代码,将任何给定的单词转换为其数字名称。

例如:国际化 = i18n(第一个字符+中间的字符数+最后一个字符)

我找到了如何找到第一个和最后一个字符,我知道如何找到数字部分,但我不知道如何将数字放在第一个和最后一个字符之间。

我用来获取数字部分的代码是:

cut -c 2- | rev | cut -c 2- | rev | tr -d [:space:]| wc -c 
Run Code Online (Sandbox Code Playgroud)

我用来获取第一个和最后一个字符的代码:

awk -F "" '{print $1,$NF}'
Run Code Online (Sandbox Code Playgroud)

Adm*_*Bee 17

虽然我发现使用awk空字段分隔符有点“创新”,但我认为最简单的解决方案只是您的一个小扩展:

awk -F "" '{print $1 (NF-2) $NF}'
Run Code Online (Sandbox Code Playgroud)

当然,这只适用于三个或更多字母的单词。处理一般情况:

awk -F "" '{if (NF>2) print $1 (NF-2) $NF; else print $0}'
Run Code Online (Sandbox Code Playgroud)

作为解释:

  • 由场分离器设置为“空”-F ""时,输入被分成场的每个字符之后,即输入的每个字符被认为是一个单独的“场”,其经由可访问$nAWK表达式(与ñ是从场号1 到NF)。顺便说一句,GNU Awk 用户指南明确提供了示例等用例,因此我纠正了我之前对使用空 FS 的担忧。不过,请注意手册中说“这是一个常见的扩展;POSIX 标准没有指定它”。
  • if字段数(即这里的字符)大于两个,打印第一个字段/字符 ( $1),计算的表达式 ( NF-2) 等于第一个和最后一个之间的字符数,以及最后一个字段/字符( $NF). 请注意,print此处使用的调用不会在各个输出标记之间产生空格;这只发生在用逗号而不是空格分隔参数时(参见例如 GNU Awk 用户指南)。
  • else 只需打印整个输入表达式,可以通过 $0

请注意,如果我们将两个字符的输入(例如 at)提供给第一个代码示例,我们会得到不需要的(但形式上正确的)输出,例如a0t(因为在这种情况下,第一个和最后一个之间有零个字符)。

还要注意,这很重要,如果您为此awk调用提供一个包含前导或尾随空格的字符串,例如 in echo " hello" | awk <etc.>,那么前导/尾随空格将被视为第一个/最后一个字符,从而产生不需要的行为!

  • 实际上,您甚至可以使用 awk 打印 `$0` 作为默认操作的事实,`=` 返回分配的值并且没有数字名称为空(*ie* 零/假)将整个内容缩短为 `awk -F '' ' $0=$1NF-2$NF'` (2认同)

Jef*_*ler 15

在 ksh93、bash 或 zsh 中:

numeronym() {
  (( ${#1} > 2 )) || return
  printf '%s%d%s\n' "${1:0:1}" "$(( ${#1} - 2 ))" "${1: -1:1}"
}
Run Code Online (Sandbox Code Playgroud)

这通过打印第一个字母、(字符数减 2)和最后一个字母对第一个(唯一)参数起作用。


jes*_*e_b 10

另一个 awk 解决方案:

awk '{l=length($1); print substr($1,1,1) l-2 substr($1,l,1)}'
Run Code Online (Sandbox Code Playgroud)
  • l=length($1)- 将l变量设置为字符串的长度(假设输入字符串在第一列中并且不包含空格)
  • substr($1,1,1) - (column #, start point, end point) 所以打印第 1 列,从位置 1 开始,并打印 1 个字符。
  • l-2 - 字符串长度减 2
  • substr($1,l,1)- 从位置l(字符串的长度)开始打印第 1 列并打印 1 个字符。


ImH*_*ere 5

可移植到许多外壳:

a=internationalization;
if [ "${#a}" -gt 2 ]; then 
    a="${a%"${a#?}"}$((${#a}-2))${a#"${a%?}"}";
fi
printf '%s\n' "${a}"
Run Code Online (Sandbox Code Playgroud)

作为一个功能(稍微不那么便携):

numeronym() {  a="$1";
               if [ "${#1}" -gt 2 ]; then 
                    a="${a%"${a#?}"}$((${#a}-2))${a#"${a%?}"}";
               fi;
               printf '%s\n' "${a}";
            }
Run Code Online (Sandbox Code Playgroud)

称之为:

$ numeronym internationalization
i18n
Run Code Online (Sandbox Code Playgroud)

如果必须是 awk:

$ echo internationalization |
      awk '{ print (NF>2) ? $1 NF-2 $NF : $0 }' FS=''

i18n
Run Code Online (Sandbox Code Playgroud)