8

I once had a script that would do the following. It would rename part of a filename of multiple files in the current directory:

For example:

rename variable1 variable2

rename 456 555

Input:

testa456testa
sama456sama
apple456applea
johna_456_johna
davida_456_davidb

Output:

testa555testa
sama555sama
apple555applea
johna_555_johna
davida_555_davidb

I don't have the script anymore, and I am still new to Unix. I need a script, that I can use from the command line.

What I do now is:

I list the files "ls * (file names)" to a temp file name. Then I do a search %/s/456/555/g. Then I move all old file names, to new file names. I was able to do this in a command line "rename $1 to $2". So, in any given directory I would line to rename middle of file names from a command line. It could be hundreds of files. Hope this make sense, Thanks Ivan

ivan
  • 411
  • 1
    What's the question? Do you want help writing a script? Finding it? Making use of alternatives? Solving this specific problem of changing 456 to 555? Please edit your text to include a question. And while you're there please tell us your UNIX flavour or Linux distribution. – Chris Davies Oct 12 '16 at 21:17
  • yes, i need a script that i can used from the command line. I am still new to Unix. What i do is "ls * (file names)" to a temp file name. then do a search %/s/456/555/g. then move all old file names to new file names. I was able to do this in a command line "rename $1 to $2". So, in any given directory i would line to rename middle of file names. It could be hundred of files. Hope this make sense, Thanks. – ivan Oct 13 '16 at 13:30
  • What UNIX flavour or Linux distribution are you using? Is there any particular reason why you haven't installed the missing rename script? – Chris Davies Oct 16 '16 at 22:41

4 Answers4

8

With only shell, using parameter expansion:

for f in *456*; do echo mv -i -- "$f" "${f//456/555}"; done

here we re iterating over the files having 456 in their names, and the parameter expansion pattern ${f//456/555} will replace all 456 substrings in the filename with 555.

The above will do the dry-run by showing what mv command will be run, you can remove echo to let the action take place:

for f in *456*; do mv -i -- "$f" "${f//456/555}"; done

With rename (prename):

rename -n 's/456/555/g' *456*

this will replace all (g) 456 substring from filenames with 555 (s/456/555/).

-n will do the dry-run, if you are satisfied with the changes to be made, remove -n to let the actual renaming take place:

rename 's/456/555/g' *456*
heemayl
  • 56,300
0

It looks like you're forgetting to pass the files to rename.

rename 456 555 *456*
0
which -a rename

Will tell you if any rename tools are on your $PATH.

rename 's/456/555/g' *

Is the preferred syntax for doing what you want (As stated in the manual). If you have no or an old version of rename without regex just download (official) prename Which is a perl script debian like systems use.

user1133275
  • 5,574
0

(Moved from a question intended as an answer here)

I have found the answer to my question:

#! /bin/csh -f
#----------------------------------------------------------------------
#  Script Name: moveme                          Date:   05/07/96
#  Written by:  John W. Woolsey                 Rev:    10/11/99
#
#  Description:
#    Renames a set of files that contain a particular search string
#    to file names that contain a replacement string.
#
#  Syntax:  moveme <search_string> <replace_string>
#
#  Where:
#     <search_string> is the name of the file name search string.
#     <replace_string> is the name of the file name replace string.
#----------------------------------------------------------------------
#
onintr catch
if ($#argv != 2) goto syntax

ls -d *$1* | sed "s/\(.*\)\$1\(.*\)/mv & \1$2\2/" | sh
exit 0

syntax:
echo "Syntax:  `basename $0` <search_string> <replace_string>"
exit 1

catch:
echo "`basename $0` was interrupted or terminated abnormally."
exit 1
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233