I have a list of directories using the format:

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


I need to change them to:

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

I’m trying to do this with for d in *\ ??-??; do mv "$d" "$d//<something>/<something>"; done but I don’t know how to do this a.) without replacing every “-“ with a “:” and b.) taking the characters referenced by the ?’s and preserve them. My efforts so far have resulted in colons replacing all hyphens, or with every series of [colon][number][number] resulting in “:??” printed literally.

Can someone explain to me how to do this or point me to the documentation that explains how to reference matched characters in order to use them in the replacement?

Additionally, can you also tell me what syntax I need to add if I want to do this recursively?

  • What operating system?
    – DavidPostill
    Dec 8, 2014 at 21:48
  • Ugh, sorry I left that out. Edited title to include that info. I'm trying to do this in Bash. Specifically Debian 7, though I doubt that part matters. Thanks.
    – rrr45
    Dec 8, 2014 at 21:57

2 Answers 2


I don't think you can do that with bash parameter expansion, but here's one way:

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

Just with bash, using a regex and capturing:

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

Another way:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.