I have a list of files (thousands of them) like this:
/path/2010 - filename.txt
/path/2011 - another file name.txt
Always following this pattern: #### - string.txt
I need to change them to look like this:
/path/filename (2010).txt
/path/another file name (2011).txt
How can I do this quickly with bash, shell, terminal, etc.?
Untested.
find /path -name '???? - *.txt' -print0 | while read -d ''; do
[[ $REPLY =~ (.*)/(....)\ -\ (.*)\.txt$ ]] || continue
path=${BASH_REMATCH[1]}
year=${BASH_REMATCH[2]}
str=${BASH_REMATCH[3]}
echo mv "$REPLY" "$path/$str ($year).txt"
done
Remove the echo
once the generated mv
commands look right.
Try rename
command:
rename -n 's/(.*) - (.*)(\.txt)/$2 ($1)$3/' *.txt
-n
(--no-act) option is for preview.
Remove -n
to perform substitution.
I know you didn't tag it with zsh
but you did say shell
. Anyway here's how to do it with the zmv
function in zsh
:
autoload zmv # It's not loaded by default
zmv -nvw '* - *.*' '$2 ($1).$3'
Remove -n
when you're happy with the output.
-v
makes zmv
verbose. -w
implicitly makes a group of each wildcard.
I'd prefer to add this as a comment, but I'm not yet allowed to.
I asked a similar question and received a number of helpful answers over here:
https://unix.stackexchange.com/questions/37355/recursively-rename-subdirectories-that-match-a-regex
Perhaps one of those solutions can be adapted to suit you needs.