Find the answer to your Linux question:
Results 1 to 3 of 3
Hi, I've just started with bash scripting, and as there's lots of help with renaming online, and the fact I that I need to rename a lot of file extensions, ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Feb 2010
    Posts
    1

    Batch renaming with basename


    Hi,
    I've just started with bash scripting, and as there's lots of help with renaming online, and the fact I that I need to rename a lot of file extensions, I thought I'd begin here.

    What I'd like to do is to create a script that means in the command line I could enter "sh script ext1 ext2 *.ext1"

    The problem I encountered is that my script only works for one file every time it is executed. Here is my script so far:
    #!/bin/sh

    Code:
    for f in $3; 
    do 
    mv "$f" "`basename "$f" $1`$2"; 
    done;
    I've realised that if I have the following, then it works for all files at once, however if I try to convert from htm to html, for example, it will convert files that are named 1.htm but will also convert 1htm.php to 1.html which is not what I need.
    Code:
    for f in *$1; 
    do 
    mv "$f" "`basename "$f" $1`$2"; 
    done;
    Any help with this would be appreciated, thanks.

  2. #2
    Linux Guru Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,252
    So when you enter something like *.ext1 into the prompt, it gets converted into the full list of files and passed to the script. This is why, in your first script, $3 only matches a single file.

    So how can we do this? The problem is that we don't know how many files there are. The files are stored in $3 all the way to some $n, where we don't know n.

    Therefore, we'll use the "shift" command. "shift" takes each parameter variable and shifts it down one. That is, $3 becomes $2, $2 becomes $1, and the old $1 vanishes. How can we take advantage of this?
    Code:
    #!/bin/bash
    
    origext=$1
    newext=$2
    
    shift
    shift
    
    while [ ! -z "$1" ]; do
        mv "$1" "$(basename "$1" "$origext")$newext"
        shift
    done
    Now it works for every argument that gets passed in.

    The case to look out for is some strange behaviour that happens if one of the files passed in doesn't have the extension that you expect (for instance, image "./rename_files html php file.cgi"). You may want to think about that.

    Do you understand how this script works?

  3. #3
    Linux User
    Join Date
    Nov 2009
    Location
    France
    Posts
    292
    Yo may also pass only 2 arguments to your script :

    Code:
    for f in *.$1
    do
    mv "$f" "`basename $f $1`$2"
     done
    That's close to your second script where you wrote :

    Code:
    for f in *$1;
    You just missed a dot !
    0 + 1 = 1 != 2 <> 3 != 4 ...
    Until the camel can pass though the eye of the needle.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •