[comp.unix.shell] Shell wildcard expansion

mike@ap542.uucp (Mike Hoffmann) (06/24/91)

Hi!

I have no idea if this is a FAQ, but anyway.

I'm looking for a wildcard expansion mechanism, where for example I could
do mv *.c *.o.
E.g. an expansion where I only get the * part. 
Another case would be, say a directory containing files
foobar foobar.c and foobar.o and when I use *.c I only get foobar, which I can
then use further.

I think this is what I want :-)
Mike

-- 
Mike Hoffmann, Siemens-Nixdorf AG, SNI AP 712  
UUCP: mike@ap542.uucp | INTERNET: mike%ap542@ztivax.siemens.com
      Berlin now is the Capital, Bonn was... 
Thank Heavens, I'm in Munich, the Capital of a different State called Bavaria!

asg@sage.cc.purdue.edu (The Grand Master) (06/25/91)

In article <1991Jun24.144854.8879@ap542.uucp> mike@ap542.uucp (Mike Hoffmann) writes:
}
}Hi!
}
}I have no idea if this is a FAQ, but anyway.
}
}I'm looking for a wildcard expansion mechanism, where for example I could
}do mv *.c *.o.
}E.g. an expansion where I only get the * part. 

Are you saying that you want
$ ls
hi.c
there.c
how.c
areyou.c
$ mv *.c *.o
$ ls
hi.o
there.o
how.o
areyou.o

If so then here is a program called rename that is written in perl.
The syntax is:
rename s/\.c/\.o/ *.c
i.e.
rename (some sort of regexp replacement a la ed) (list of files on which to
                             			   perform this replacement)

Here it is

---------------cut here--------------
#! /usr/unsup/bin/perl
'di';
'ig00';
#
# $Header: /userb/asg/bin/RCS/rename,v 1.0 91/03/20 10:51:47 asg Exp Locker: asg $
#
# $Log:	rename,v $
# Revision 1.0  91/03/20  10:51:47  asg
# Initial revision
# 
# Revision 3.0.1.2  90/08/09  03:17:57  lwall
# patch19: added man page for relink and rename
# 

if ($ARGV[0] eq '-i') {
    shift;
    if (open(TTYIN, "</dev/tty") && open(TTYOUT,">/dev/tty")) {
	$inspect++;
	select((select(TTYOUT),$|=1)[0]);
    } 
}
($op = shift) || die "Usage: rename [-i] perlexpr [filenames]\n";
if (!@ARGV) {
    @ARGV = <STDIN>;
    chop(@ARGV);
}
for (@ARGV) {
    unless (-e) {
	print STDERR "$0: $_: $!\n";
	$status = 1;
	next;
    } 
    $was = $_;
    eval $op;
    die $@ if $@;
    if ($was ne $_) {
	if ($inspect && -e) {
	    print TTYOUT "remove $_? ";
	    next unless <TTYIN> =~ /^y/i;
	} 
	unless (rename($was, $_)) {
	    print STDERR "$0: can't rename $was to $_: $!\n";
	    $status = 1;
	}
    } 
}
exit $status;
------------cut here-------------

Hope this helps

			Bruce
---------
                                   ###             ##
Courtesy of Bruce Varney           ###               #
aka -> The Grand Master                               #
asg@sage.cc.purdue.edu             ###    #####       #
PUCC                               ###                #
;-)                                 #                #
;'>                                #               ##

ars@cs.brown.edu (Adam Stauffer) (06/25/91)

}I'm looking for a wildcard expansion mechanism, where for example I could
}do mv *.c *.o.
}E.g. an expansion where I only get the * part. 

There is a really nifty program called "mmv" that allows for all sorts
of fun expansions to occur.  It is available at uunet.uu.net in vol 21
of the comp.sources.unix archive...

-adam

tchrist@convex.COM (Tom Christiansen) (06/25/91)

From the keyboard of ars@cs.brown.edu (Adam Stauffer):
:
:}I'm looking for a wildcard expansion mechanism, where for example I could
:}do mv *.c *.o.
:}E.g. an expansion where I only get the * part. 
:
:There is a really nifty program called "mmv" that allows for all sorts
:of fun expansions to occur.  It is available at uunet.uu.net in vol 21
:of the comp.sources.unix archive...

Maybe you didn't look much at rename script that was posted.  It 
allows things like:

# strip .bak from files
    rename 's/\.bak$//' *.bak

# call all fortran files nasty
    rename 's/\.f$/.EVIL/' *.f

# make uppercase files be lowercase
    rename 'tr/A-Z/a-z/' *

# make lowercase unless the filename starts with "Make"
    rename 'tr/A-Z/a-z/ unless /^Make/' *

# change all files in entire system of form foo~ into .#foo
    find / -name '*~' -print | rename 's/(.*)~/.#$1/' 

# change foo to bar if the user types yes after seeing the name
    rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i'  *

# make xxx44 into 02C-xxx  
    rename '/^(\D*)(\d+)$/ && $_ = sprintf("%03X-%s", $2, $1)' *


The possibilities are literaly limitless.  Ok, the last two are admittedly
a trifle baroque, but you get the idea.  The version posted was a bit
elaborate (reads files from stdin, groks -i option, error checking, etc.)

The real guts are just:

	#!/usr/bin/perl
        $op = shift;
        for (@ARGV) {
            $was = $_;
            eval $op;
            die $@ if $@;
            rename($was,$_) unless $was eq $_;
        }

So if you ever misplace it, you can always rewrite it.

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time."  

ars@cs.brown.edu (Adam Stauffer) (06/25/91)

In article <1991Jun24.195425.26387@convex.com> 
	tchrist@convex.COM (Tom Christiansen) writes:

   From the keyboard of ars@cs.brown.edu (Adam Stauffer):
   :
   :}I'm looking for a wildcard expansion mechanism, where for example I could
   :}do mv *.c *.o.
   :}E.g. an expansion where I only get the * part. 
   :
   :There is a really nifty program called "mmv" that allows for all sorts
   :of fun expansions to occur.  It is available at uunet.uu.net in vol 21
   :of the comp.sources.unix archive...

   Maybe you didn't look much at rename script that was posted.  It 
   allows things like:

Maybe you have never seen mmv so you don't know what it does.
Trust me, I wouldn't have posted if it didn't have more functionality
than a 30 line Perl script. 

-a

pfalstad@phoenix.princeton.edu (Paul Falstad) (06/25/91)

Warning!  zsh plug ahead.  Sensitive readers hit 'n'.

$ /usr/local/bin/zsh
% rename () { eval 'shift; for i; mv $i $i:'$1 }

tchrist@convex.COM (Tom Christiansen) wrote:

># strip .bak from files
>    rename 's/\.bak$//' *.bak

% rename s/.bak// *.bak

># call all fortran files nasty
>    rename 's/\.f$/.EVIL/' *.f

% rename s/.f/.EVIL/ *.f

># make uppercase files be lowercase
>    rename 'tr/A-Z/a-z/' *

% rename l *

># make lowercase unless the filename starts with "Make"
>    rename 'tr/A-Z/a-z/ unless /^Make/' *

% set -o extendedglob
% rename l ^Make*

># change all files in entire system of form foo~ into .#foo
>    find / -name '*~' -print | rename 's/(.*)~/.#$1/' 

Afraid my rename can't tackle this one.  Try this though:

% for i in /..../*~; mv $i ".#${i%~}"

># change foo to bar if the user types yes after seeing the name
>    rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i'  *

% for i in *; if read "j?$i: "; [[ $j = y* ]]; then mv $i $i:s/foo/bar/; fi

># make xxx44 into 02C-xxx  
>    rename '/^(\D*)(\d+)$/ && $_ = sprintf("%03X-%s", $2, $1)' *

Oh well.

>So if you ever misplace it, you can always rewrite it.

Since my rename function is so simple, I don't bother to define it;
I usually just type out the zsh commands to do what I want:

% for i in *.bak; mv $i $i:s/.bak//

However, if you have a filename like "foo.bak.bar.bak",
then $i:s/.bak// will give "foo.bar.bak" instead of
the desired "foo.bak.bar"; ${i%.bak} does what you want.

--
Paul Falstad                     | 10 PRINT "PRINCETON CS"
pfalstad@phoenix.princeton.edu   | 20 GOTO 10

suley@xantos.uio.no (Suleyman Kondakci) (06/25/91)

Here is a simple csh-script, which renames its *.c args to *.o files:

#! /bin/csh
if ($#argv) then
	foreach from ($*)
		set renew = `echo $from:r`
		echo moving $from to $renew.o
		mv $from $renew.o
	end
exit 0
endif
# Didn't exit safely
cat <<EOF
`clear`

Syntax: $0 from_1.c from_2.c  to_1.o to_2.o ...
EOF

tchrist@convex.COM (Tom Christiansen) (06/25/91)

From the keyboard of suley@xantos.uio.no (Suleyman Kondakci):
:
:Here is a simple csh-script, which renames its *.c args to *.o files:
:
:#! /bin/csh
:if ($#argv) then
:	foreach from ($*)
:		set renew = `echo $from:r`
:		echo moving $from to $renew.o
:		mv $from $renew.o
:	end
:exit 0
:endif
:# Didn't exit safely
:cat <<EOF
:`clear`
:
:Syntax: $0 from_1.c from_2.c  to_1.o to_2.o ...
:EOF


I prefer this one:  :-)

    #!/bin/csh -f
    foreach file ($*) 
	cc -c $file && rm -f $file
    end


Really guys, we can all spin little shellamabobs to do this kind of thing.
The interesting ones are the open-ended ones.  Plus, heh, isn't this a FAQ?

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time."