Squirt: Moving Files Around Using Bash

I needed to copy all files with the string “_1” in them to a separate folder and remove the “_1”. I thought I could pull this with a one liner, but that wasn’t happening. A two liner had to do:

# find . -name "*_1.jpg" -exec cp {} ../xx/ \;
# for file in *_1.jpg; do mv $file "$(basename $file _1.jpg).jpg"; done

A brief explanation of the above.

I usually use find/xargs quite a bit, such as removing .svn directories when I forget to export. This wouldn’t work in this situation, because I needed to use the result of the find as an argument within my next command and the pipe wouldn’t do. So the -exec flag of find will pass the match as an argument that can be used with the syntax {}. The semi-colon denotes the end of the command and I’m escaping it with a backslash. So this reads “find all files in the current directory that end in _1.jpg and move them to ../xx/.”

The second command I ran within the “xx” directory. The basename string manipulation let me strip the _1.jpg from the name, then I re-added .jpg and this is all within the quotes so it comes out as a single file name. So this reads “for every file in this directory that ends in *_1.jpg, rename by removing _1.jpg then adding .jpg to the end.”

I guess this could have been done in one line, but whatever.

2 thoughts on “Squirt: Moving Files Around Using Bash”

  1. Hmm… this doesn’t work?

    $ for file in *_1.jpg; do mv $file ../xx/”$(basename $file _1.jpg).jpg”; done

    Unless you want to find files in subdir as well, then

    $ for file in `find . -name “*_1.jpg”`; do mv $file ../xx/”$(basename $file _1.jpg).jpg”; done

Leave a Reply

Your email address will not be published. Required fields are marked *