You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Bash数组元素中移除数字下划线前缀?

问题描述

我有如下Bash数组:

names=( 12_1_3_4_NAME1 1_2_4_NAME2 2_1_name3 1_nAmE4)

希望移除每个元素开头的数字下划线组成的前缀,得到:

names=( NAME1 NAME2 name3 nAmE4 )

我尝试了以下写法但未成功:

names=( "${names[@]/^\d+(?:\_\d+)/}" )
names=( "${names[@]//s*^\d+(?:\_\d+)+\s*/}" )

不清楚如何在Bash数组中正确实现该操作。

可行解决方案

Bash的参数展开不支持Perl风格正则(比如\d、非捕获组(?:...)),仅支持POSIX基本正则表达式,且参数展开的单斜杠替换默认匹配字符串开头,无需额外加^。下面是两种可行实现方式:

方法1:开启extglob扩展后用参数展开

先开启Bash的extglob扩展(支持+(pattern)语法,匹配一个或多个指定模式):

shopt -s extglob

然后直接批量处理数组元素:

names=( "${names[@]//+([0-9]_)/}" )

这条命令会把每个元素开头所有数字+下划线的重复片段替换为空,刚好符合需求。

方法2:循环结合sed处理

如果不想开启extglob,可以用循环遍历数组,通过sed处理每个元素:

new_names=()
for name in "${names[@]}"; do
    new_names+=( "$(sed 's/^\([0-9]\+_\)\+//' <<< "$name")" )
done
names=( "${new_names[@]}" )

sed的正则^\([0-9]\+_\)\+表示匹配开头一个或多个数字串+下划线的组合,替换为空后就得到目标字符串。

原写法失败原因

  • Bash不支持\d,需用[0-9]或[[:digit:]]表示数字
  • 不支持非捕获组(?:...),extglob的+(...)是等价的多次匹配语法
  • 原写法中多余的s*和\s*属于错误匹配,原数组元素开头没有空白字符
  • 参数展开的替换语法中,单斜杠/是只替换一次匹配,双斜杠//是全局替换,但这里需要匹配重复的前缀,所以要用全局替换或extglob的多次匹配

内容的提问来源于stack exchange,提问作者Gabriel G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:47:12