【问题标题】:Cut string of numbers at letter in bash在bash中的字母处剪切数字字符串
【发布时间】:2022-01-04 00:06:10
【问题描述】:

我有一个字符串,例如plantford1775.274.284b63.11

我一直用identity=$( echo "$identity" | cut -d'.' -f3)在每个点上剪切,然后选择第三部分。我留下了284b63

这部分的格式总是一个字母,中间夹着不同数量的数字。我想取字母前的前几个数字。示例代码行如下:

identity=$( echo "$identity" | cut -d'anyletter' -f1)

我应该用什么替换anyletter 来剪切那里列出的任何字母,这样我就以284 的字符串结尾?

【问题讨论】:

    标签: bash shell awk cut


    【解决方案1】:

    这可以在单个awk 中完成,请尝试使用您显示的示例进行以下编写和测试。

    echo "$identity" | awk -F'.' '{sub(/[^0-9].*/,"",$3);print $3}'
    

    解释: 简单的解释是,将echo 命令的输出作为标准输入传递给awk 代码。在awk 程序中,将字段分隔符设置为. 用于值。然后在第三字段替换(使用awksub 函数)除第三字段中带有NULL 的数字之外的所有内容,然后打印。

    【讨论】:

    • 你也是。很好的解决方案。
    • 这将打印出28463,这不是预期的输出。也许您的意思是sub(/[^0-9].*/,"",$3),而不是gsub(/[^0-9]*/,"",$3)
    • @M.NejatAydin,非常感谢您的收获,我现在已经编辑了我的代码,我在解释 sub 中编写(提及)但不知何故在脚本中编写了 gsub,谢谢。
    【解决方案2】:

    试试:

    echo plantford1775.274.284b63.11 | cut -d. -f3 | sed 's/[a-z].*//'
    

    【讨论】:

    • 解决方案最终是这样,但由于其他原因,我不得不删除 -d 参数并将这一行仅用于 284b63。 identity=$( echo "$identity" | cut -f3 | sed 's/[a-z].*//')
    【解决方案3】:

    或者对 REGEX 稍作改动,在 bash 中使用 [[...]]

    v="plantford1775.274.284b63.11"
    [[ $v =~ ^[^.]+.[^.]+.([^.]+).*$ ]] && echo ${BASH_REMATCH[1]}
    

    输出

    284b63
    

    或者如果您只对字母前的数字感兴趣:

    [[ $v =~ ^[^.]+.[^.]+.([[:digit:]]+)[^.]+.*$ ]] && echo ${BASH_REMATCH[1]}
    

    输出

    284
    

    【讨论】:

      【解决方案4】:

      使用bash,使用=~ 运算符:

      [[ $identity =~ [^.]*.[^.]*.([0-9]+) ]] && identity=${BASH_REMATCH[1]}
      

      或者,在 POSIX shell 中:

      identity=${identity#*.*.}
      identity=${identity%%[^0-9]*}
      

      或者,使用sed

      identity=$(sed 's/[^.]*.[^.]*.\([0-9]*\).*/\1/' <<< "$identity")
      

      【讨论】:

        【解决方案5】:

        也许您可以使用 bash 正则表达式并从 $BASH_REMATCH 获取结果。

        [[ "$identity" =~ ([0-9]+)[a-z][0-9]+ ]] && identity="${BASH_REMATCH[1]}"
        

        【讨论】:

          【解决方案6】:

          说我们有

           identity=284b63
          

          那么你可以做一个

           lead=${identity%[a-z]*}
          

          lead 设置为284。随意将模式调整为大写字母和/或其他分隔符。

          【讨论】:

            【解决方案7】:

            如果这部分的格式总是一个字母,中间夹着不同数量的数字,而你想匹配这种格式,你也可以使用gnu awk,将字段分隔符设置为@ 987654322@ 并为第三个字段使用带有捕获组的模式。

            该模式从字符串的开头捕获 1 个或多个数字,并匹配多个字符 [a-z] 后跟一个数字中的一个。

            echo "$identity" | awk -F'.' 'match($3, /^([0-9]+)[a-z]+[0-9]/, ary) {print ary[1]}'
            

            输出

            284
            

            或者使用 sed 与前 2 个点和第 2 个点之后的捕获组匹配的模式:

            identity=$(sed 's/^[^.]\+\.[^\.]\+\.\([0-9]\+\)[a-z]\+[0-9].*/\1/' <<< "$identity")
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-11-29
              • 2013-01-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-12-29
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多