views:

1169

answers:

5

Is there a one line command in tcsh to change the extension of a set of files? In the various DOS shells, I used to use the following:

ren *.abc *.def

This would rename all files ending in .abc to end instead with .def. In sed terms this would perform something like the following:

sed -e 's/\(.\)*\.abc$/\1.def/'

on the file names. I could probably throw bits and pieces together to achieve something similar in *nix, but I'm guessing that the issue here is my lack of experience with tcsh.

Any help appreciated.

+2  A: 

I don't know if tcsh provides an easier way to do this, but here's what I usually do:

ls *.abc | sed 's/\(.*\)\.abc/mv "\1.abc" "\1.def"/' | sh

I have also written a Python script called regexmv that renames files using regular expressions. Here's the script:

import os
import re
import sys
import os.path

def main(argv):
    dry_run = True
    if argv[0] == '-f':
        dry_run = False
        argv = argv[1:]

    pattern = argv[0]
    repl    = argv[1]
    files   = argv[2:]

    max_length = max([len(f) for f in files])

    for f in files:
        new = re.sub(pattern, repl, f)
        if f != new:
            if not os.path.exists(new):
                print "%s --> %s" % (f.ljust(max_length), new)
                if not dry_run:
                    os.rename(f, new)

if __name__ == '__main__':
    main(sys.argv[1:])

I first run it like this:

regexmv '\.abc$' '.def' *

to see which files will be renamed (and how they will be renamed), and if this is what I want, I run it like:

regexmv -f '\.abc$' '.def' *
Can Berk Güder
+4  A: 

Type in these four lines. After the first the prompt, tcsh will tell you that you are inside the foreach loop. You could also turn it into a shell script and call that shell script.

foreach n ( `ls *.abc` )
set base = `basename $n .abc`
mv $n $base.def
end
Chas. Owens
A: 

In *nix world there was no concept of "extension". The 'dot abc' is just part of the filename. There is a perl script to mimic the behavior here.

I am sorry I can't provide tcsh, but there is a bash idiom:

for f in *.foo; do
    mv $f ${f%foo}bar
done
Marcelo Morales
+1  A: 

In addition to what others have said, many UNIX flavors provide a command called "rename". If your goal is to rename files using tcsh, specifically, then this won't help you. Otherwise, you can achieve your goal with:

rename abc def *.abc

It's a very simple-minded and very useful command. In the list of files provided by the 3rd argument, it replaces all occurrences of the 1st argument with the second. At least in the versions I am familiar with, there is no pattern matching at all, except to the degree that your shell will expand patterns in the list of files for the 3rd argument.

Eddie
A: 

[Collating answers - what the questioner got from the responses]:

There is no easy way to change a group of files' names in tcsh. Chas. provided the simplest solution in tcsh, but it still wasn't easy.

The best way to do what I'm after if you're using tcsh as your shell is using the external rename command (see Eddie's answer).

I appreciate that this is not what I actually asked in the question - but what I learnt is that my question was wrong!

Thanks to everybody that replied, your answers were very helpful - each in a slightly different way. If somebody would like to summarise the results of this question in a better way than I have, please do. I'd much prefer to give my "accepted answer" to somebody else!

kwutchak