Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

Unix - Frequently Asked Questions (2/7) [Frequent posting]
Section - How do I rename "*.foo" to "*.bar", or change file names to lowercase?

( Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Single Page )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Business Photos and Profiles ]


Top Document: Unix - Frequently Asked Questions (2/7) [Frequent posting]
Previous Document: How do I read characters from the terminal in a shell script?
Next Document: Why do I get [some strange error message] when I "rsh host command" ?
See reader questions & answers on this topic! - Help others by sharing your knowledge

2.6)  How do I rename "*.foo" to "*.bar", or change file names to lowercase?
        
      Why doesn't "mv *.foo *.bar" work?  Think about how the shell
      expands wildcards.   "*.foo" and "*.bar" are expanded before the
      mv command ever sees the arguments.  Depending on your shell,
      this can fail in a couple of ways.  CSH prints "No match."
      because it can't match "*.bar".  SH executes "mv a.foo b.foo
      c.foo *.bar", which will only succeed if you happen to have a
      single directory named "*.bar", which is very unlikely and almost
      certainly not what you had in mind.

      Depending on your shell, you can do it with a loop to "mv" each
      file individually.  If your system has "basename", you can use:

      C Shell:
        foreach f ( *.foo )
            set base=`basename $f .foo`
            mv $f $base.bar
        end

      Bourne Shell:
        for f in *.foo; do
            base=`basename $f .foo`
            mv $f $base.bar
        done

      Some shells have their own variable substitution features, so
      instead of using "basename", you can use simpler loops like:

      C Shell:

        foreach f ( *.foo )
            mv $f $f:r.bar
        end

      Korn Shell:

        for f in *.foo; do
            mv $f ${f%foo}bar
        done

      If you don't have "basename" or want to do something like
      renaming foo.* to bar.*, you can use something like "sed" to
      strip apart the original file name in other ways, but the general
      looping idea is the same.  You can also convert file names into
      "mv" commands with 'sed', and hand the commands off to "sh" for
      execution.  Try

        ls -d *.foo | sed -e 's/.*/mv & &/' -e 's/foo$/bar/' | sh

      A program by Vladimir Lanin called "mmv" that does this job
      nicely was posted to comp.sources.unix (Volume 21, issues 87 and
      88) in April 1990.  It lets you use

        mmv '*.foo' '=1.bar'

      Shell loops like the above can also be used to translate file
      names from upper to lower case or vice versa.  You could use
      something like this to rename uppercase files to lowercase:

        C Shell:
            foreach f ( * )
                mv $f `echo $f | tr '[A-Z]' '[a-z]'`
            end
        Bourne Shell:
            for f in *; do
                mv $f `echo $f | tr '[A-Z]' '[a-z]'`
            done
        Korn Shell:
            typeset -l l
            for f in *; do
                l="$f"
                mv $f $l
            done

      If you wanted to be really thorough and handle files with `funny'
      names (embedded blanks or whatever) you'd need to use

        Bourne Shell:

            for f in *; do
              g=`expr "xxx$f" : 'xxx\(.*\)' | tr '[A-Z]' '[a-z]'`
              mv "$f" "$g"
            done

      The `expr' command will always print the filename, even if it
      equals `-n' or if it contains a System V escape sequence like `\c'.

      Some versions of "tr" require the [ and ], some don't.  It
      happens to be harmless to include them in this particular
      example; versions of tr that don't want the [] will conveniently
      think they are supposed to translate '[' to '[' and ']' to ']'.

      If you have the "perl" language installed, you may find this
      rename script by Larry Wall very useful.  It can be used to
      accomplish a wide variety of filename changes.

        #!/usr/bin/perl
        #
        # rename script examples from lwall:
        #       rename 's/\.orig$//' *.orig
        #       rename 'y/A-Z/a-z/ unless /^Make/' *
        #       rename '$_ .= ".bad"' *.f
        #       rename 'print "$_: "; s/foo/bar/ if <stdin> =~ /^y/i' *

        $op = shift;
        for (@ARGV) {
            $was = $_;
            eval $op;
            die $@ if $@;
            rename($was,$_) unless $was eq $_;
        }

User Contributions:

Comment about this article, ask questions, or add new information about this topic:

CAPTCHA




Top Document: Unix - Frequently Asked Questions (2/7) [Frequent posting]
Previous Document: How do I read characters from the terminal in a shell script?
Next Document: Why do I get [some strange error message] when I "rsh host command" ?

Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Single Page

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
tmatimar@isgtec.com (Ted Timar)





Last Update March 27 2014 @ 02:12 PM