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

如何在Bash中将重复单词处理为dup,dup(1),dup(2)格式?

解决Bash字符串重复元素添加序号的问题

我来帮你搞定这个需求~你已经迈出了正确的第一步:把逗号分隔的字符串拆成数组,接下来只需要跟踪每个元素的出现次数,就能给重复元素加上递增序号了。

完整实现代码

string="lisp,pascal,lisp,bash,bash,bash,lisp"
set -f  # 禁用通配符扩展,避免特殊字符(比如*)被意外解析
array=(${string//,/ })

# 声明关联数组,用于记录每个元素已出现的次数(Bash 4.0+支持)
declare -A element_counter

# 遍历数组处理每个元素
processed_result=""
for elem in "${array[@]}"; do
    # 初始化计数:如果元素是第一次出现,计数设为0
    [[ -z "${element_counter[$elem]}" ]] && element_counter[$elem]=0

    if [[ ${element_counter[$elem]} -eq 0 ]]; then
        # 第一次出现,直接保留原元素
        processed_result+="${elem},"
    else
        # 重复出现,添加序号(序号=当前计数)
        processed_result+="${elem}(${element_counter[$elem]}),"
    fi

    # 计数自增,为下一次出现做准备
    ((element_counter[$elem]++))
done

# 去掉结果末尾多余的逗号,输出最终内容
echo "${processed_result%,}"

代码关键点解释

  • 关联数组element_counter:用来存储每个元素已经出现的次数,比如第一次遇到lisp时计数为0,第二次遇到时计数已经变成1,所以输出lisp(1)。
  • set -f:非常重要!它会禁用Bash的通配符扩展,避免如果字符串里包含*、?这类字符时,被解析成目录文件列表。
  • 末尾逗号处理:用${processed_result%,}去掉最后一个多余的逗号,比用sed更高效。

运行结果

执行这段代码后,会输出你期望的结果:

lisp,pascal,lisp(1),bash,bash(1),bash(2),lisp(2)

兼容低版本Bash(可选)

如果你的Bash版本低于4.0(不支持关联数组),可以用普通数组+循环计数的方式替代,不过这种方法效率稍低:

string="lisp,pascal,lisp,bash,bash,bash,lisp"
set -f
array=(${string//,/ })

processed_result=""
for i in "${!array[@]}"; do
    current_elem=${array[$i]}
    # 统计当前元素在之前出现的次数
    count=0
    for ((j=0; j<i; j++)); do
        [[ ${array[$j]} == "$current_elem" ]] && ((count++))
    done
    if [[ $count -eq 0 ]]; then
        processed_result+="${current_elem},"
    else
        processed_result+="${current_elem}($count),"
    fi
done

echo "${processed_result%,}"

内容的提问来源于stack exchange,提问作者carlson john

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:02:27