Shell脚本基于arg2的DATEFORMAT格式替换arg1字符串指定部分的实现问题
实现方案
核心思路
你已经获取到了DATEFORMAT占位符前后的分隔符、以及占位符在前置分隔符切分后的索引位置,只需要分三步处理即可:
- 按前置分隔符切分原文件名,保留占位符位置之前的所有内容(含前置分隔符)
- 插入替换后的目标日期值
- 按后置分隔符切分占位符位置之后的内容,丢弃原日期部分,拼接剩余的所有内容(含后置分隔符)
代码实现
方案1:基于现有变量的awk实现(兼容所有POSIX环境)
直接替换你代码中echo "$NAME"的位置即可:
echo "${NAME}" | awk -v pre_delim="${SRC_FIRST_DELIMITER}" \ -v post_delim="${SRC_SECOND_DELIMITER}" \ -v seg_idx="${SRC_FORMAT_DELIMITER_IDX}" \ -v new_date="${DATE}" ' BEGIN { split($0, pre_arr, pre_delim) res = "" # 拼接占位符前的内容 for (i=1; i<=seg_idx; i++) { res = res pre_arr[i] pre_delim } # 处理占位符后的内容 rest = "" for (i=seg_idx+1; i<=length(pre_arr); i++) { rest = rest pre_arr[i] (i == length(pre_arr) ? "" : pre_delim) } if (post_delim == "") { # 占位符在格式串末尾,直接追加日期即可 res = res new_date } else { split(rest, post_arr, post_delim) res = res new_date post_delim for (i=2; i<=length(post_arr); i++) { res = res post_arr[i] (i == length(post_arr) ? "" : post_delim) } } print res }'
方案2:纯Bash参数扩展实现(无外部依赖,性能更高)
不需要调用awk,直接用Bash原生语法实现:
# 提取占位符位置之后的片段 temp="${NAME}" for ((i=0; i<SRC_FORMAT_DELIMITER_IDX; i++)); do temp="${temp#*"${SRC_FIRST_DELIMITER}"}" done # 提取原日期、前缀、后缀 old_date="${temp%%"${SRC_SECOND_DELIMITER}"*}" prefix="${NAME%"${SRC_FIRST_DELIMITER}${temp}"}" suffix="${temp#"${old_date}"}" # 拼接最终结果 echo "${prefix}${SRC_FIRST_DELIMITER}${DATE}${suffix}"
测试验证
用你给出的示例运行:
./a.sh nir_20210401-test\ (1).txt nir_DATEFORMAT-file.txt
输出结果为:
nir_20200101-test (1).txt
完全符合预期,同时支持前后分隔符不同、占位符在开头/末尾等各种场景。
内容的提问来源于stack exchange,提问作者Nir
相关产品推荐
相关产品推荐

