3

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.?

4 Answers 4

6

Try rename command:

rename -n 's/(.*) - (.*)(\.txt)/$2 ($1)$3/' *.txt 

-n(--no-act) option is for preview.
Remove -n to perform substitution.

Sign up to request clarification or add additional context in comments.

4 Comments

Shoot, my Mac doesn't have rename (-bash: rename: command not found). Can I do this with mv?
If *.txt expands to too many files for one command line, find /path -name '*.txt' -print0 | xargs -0 rename -n ...
rename is a tiny perl script. I think you can install it in MAC.
Love rename, especially the -n part
3

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.

3 Comments

How can I add slashes to escape the spaces in the path and file names?
(.*) should greedily match everything up to the final slash, spaces and all. '\ ' is escaping the spaces in the file name proper. I don't think there should be any other issues with spaces.
Doh, unescaped spaces only showed up in echo. Mv worked just fine. Thanks. Giving you the "answer" because it worked without another library. Thanks again.
2

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.

Comments

1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.