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.
Popularity: unranked [?]
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
True. You should use -xdev to limit recursion, but the stock version of find in OS X 10.5.6 doesn’t support that. You would have to use -maxdepth. Thanks for the one liner.