2

I have a group of files named like title_december_word1_word2.png and want to iterate through the directory and swap word1 and word2 within each file.

i.e. go from button_december_state_pressed.png -> button_december_pressed_state.png

Any suggestion on how I might accomplish this?

Most batch programs I've found for OS X can't specify a char to break down words and I was hoping someone could help me with a quick script to solve this.

2 Answers 2

2

In bash, it can be done as follows:

  for i in *; do echo $i | awk -F'[_.]' '{print $1"_"$2"_"$4"_"$3 }' ; done

This command first finds all files in the current directory, then feeds these names (it assumes without checking that there are three underscores and a . in these file names) to awk, which rearranges them in the order you wish.

The only tricky part is -F'[_.]' The option -F' ' is used to identify the delimiter between different fields, and in this last case the delimiter takes on its default value, a space. But the option -F'[_.]' defines a character class of interchangeable elements, in this case underscore and dot, which can be used at will as delimiters.

Edit:

Ok, since this works, without actually moving anything, we can now implement the actual act of renaming the files:

  for i in *; do ni=$(echo $i | awk -F'[_.]' '{print $1"_"$2"_"$4"_"$3"."$5 }') && mv "$i" "$ni" ; done
6
  • This works, but how can i now apply those changes to the actual files names? Dec 5, 2013 at 16:07
  • OK. Now see my edit. Dec 5, 2013 at 16:09
  • it prints in the terminal window and script is in the same directory as the the files but it just prints out the correction, but the files themselves have not been modified with new names. Dec 5, 2013 at 16:10
  • wouldn't 'rename' have to be used to change the file name not just print it? Dec 5, 2013 at 16:16
  • @user1911904 Sorry, I forgot to say I was being cautious, letting you see what would happen before actually doing it. Now my edited post has the actual command. And it uses mv, not rename, which is kinda different. Dec 5, 2013 at 16:19
2

Zsh and zmv

If you have zsh (which comes default in OS X) you can use zmv:

% zsh
% autoload -U zmv
% zmv 'title_december_(*)_(*).png' 'title_december_$2_$1.png'

Would run the following command (use zmv -n to do a dry run without actually renaming):

mv -- title_december_word1_word2.png title_december_word2_word1.png

Obviously you can be a little more flexible if the first parts are different per image:

% zmv '(*)_(*)_(*).png' '$1_$3_$2.png' 
mv -- foo_bar_word1_word2.png foo_bar_word2_word1.png
mv -- title_december_word1_word2.png title_december_word2_word1.png

This works because the matches are greedy and therefore swallow all underscores up until the last one before the other match groups.


Perl-style rename

On OS X you can get rename with Homebrew:

$ rename -n 's/(.*)_(.*)_(.*).png/$1_$3_$2.png/' *
'foo_bar_word1_word2.png' would be renamed to 'foo_bar_word2_word1.png'
'title_december_word1_word2.png' would be renamed to 'title_december_word2_word1.png'

The -n option only prints what would have been renamed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .