How can I rename directories from “[YYYY] Title” or “(YYYY) Title” to “YYYY - Title”?

August 4, 2026 3 answers
Asked by MellowCedar42
I have a directory containing several subdirectories whose names begin with a four-digit year. Each name follows either "[YYYY] Title" or "(YYYY) Title", and I want to rename them to "YYYY - Title". I'm still learning Bash and was considering looping over the directories, extracting the year with a regular expression, and then using mv to apply the new name. What's a safe and reasonably simple way to do this?

Answers

CopperWren53
If you prefer regular expressions, Bash stores captured groups in `BASH_REMATCH`. This matches either kind of opening and closing bracket and captures the year and title: ```bash for d in */; do d=${d%/} if [[ $d =~ ^[([0-9]{4})] (.*)$ || $d =~ ^(([0-9]{4})) (.*)$ ]]; then year=${BASH_REMATCH[1]} title=${BASH_REMATCH[2]} new="$year - $title" printf '%q -> %qn' "$d" "$new" # mv -- "$d" "$new" fi done ``` The `*/` glob limits the loop to entries that look like directories, and removing the trailing slash makes the string easier to work with. Test with `printf` before enabling `mv`, especially if two source directories could produce the same destination name.
Reply to this answer
SilverMaple26
For a small number of directories, an interactive tool such as `vidir` can be less error-prone. It opens a listing in your editor; you change the names in the listing and save it, and the tool performs the corresponding renames. That gives you a chance to review every change without writing a script.
Reply to this answer
QuietHarbor7
You can do this entirely in Bash with a pattern loop and parameter expansion. This version only considers directories, handles both bracket styles, prints each change first, and avoids overwriting an existing destination: ```bash for d in ([0-9][0-9][0-9][0-9]) * [[0-9][0-9][0-9][0-9]] *; do [ -d "$d" ] || continue year="${d:1:4}" title="${d:7}" new="${year} - ${title}" if [ -e "$new" ]; then printf 'Skipping: destination already exists: %sn' "$new" >&2 continue fi printf 'Would rename: %q -> %qn' "$d" "$new" # mv -- "$d" "$new" done ``` Once the output looks right, uncomment the `mv` line. Keeping the old name and new name quoted is important because titles may contain spaces or shell characters.

BrightPanda18: The `[ -d "$d" ]` check is useful here because the glob can also remain literal when nothing matches, and it prevents accidentally processing regular files.

Reply to this answer

Add your answer

Answers are reviewed before publication.

Related Discussions