在 Bash 中,无法替换遵循特定格式的目录中的特定连字符

在 Bash 中,无法替换遵循特定格式的目录中的特定连字符

我有一个使用以下格式的目录列表:

2014-12-03 13-03
2014-09-03 12-07

ETC。

我需要将它们更改为:

2014-12-03 13:03
2014-09-03 12:07

我正在尝试这样做for d in *\ ??-??; do mv "$d" "$d//<something>/<something>"; done,但我不知道如何做到这一点:a.) 不将每个“-”替换为“:”;b.) 提取“?”引用的字符并保留它们。到目前为止,我的努力结果是冒号替换所有连字符,或者每个 [冒号][数字][数字] 系列导致“:??”逐字打印。

有人可以向我解释如何做到这一点,或者向我指出解释如何引用匹配的字符以便在替换中使用它们的文档吗?

此外,如果我想递归执行此操作,您还能告诉我需要添加什么语法吗?

答案1

我认为你不能用 bash 参数扩展来做到这一点,但这里有一种方法:

$ d="2014-12-03 13-03"
$ new=$(sed -r 's/-([^-]+)$/:\1/' <<< "$d")
$ echo "$new"
2014-12-03 13:03

只需使用 bash,使用正则表达式并捕获:

$ [[ $d =~ (.*)\ (..)-(..)$ ]] &&  printf -v new "%s %s:%s" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
$ echo "$new"
2014-12-03 13:03

答案2

其他方式:

find . -type d -name "2014*" -print0 | while read -d $'\0' file
do
    mv "$file" "$(echo $file | sed -r s/\(.*\)-\([^-]+\)$/\\1:\\2/g)"
done

相关内容