[comp.unix.questions] moving upper case names to lower case

Leisner.Henr@xerox.com (Marty) (08/22/89)

I'm looking for a good, clean way to move files from upper case names to lower case names.

i.e. FOO.C to foo.c

I could always right a C program, but there gotta be a better way.

Please send mail and I'll summarize and post.

marty
ARPA:	leisner.henr@xerox.com
GV:  leisner.henr
NS:  leisner:wbst139:xerox
UUCP:	hplabs!arisia!leisner
 

john@chinet.chi.il.us (John Mundt) (08/22/89)

In article <20672@adm.BRL.MIL> Leisner.Henr@xerox.com (Marty) writes:
>I'm looking for a good, clean way to move files from upper case names to lower case names.
>
>i.e. FOO.C to foo.c
>
>I could always right a C program, but there gotta be a better way.
>

#include <stdio.h>
#include <ctype.h>

main()
{
	register int c;
	while ((c = getchar()) != EOF)
		putchar(tolower(c));
}

It's easier to write and compile this than to get tr to massage
the string for you.  
-- 
---------------------
John Mundt   Teachers' Aide, Inc.  P.O. Box 1666  Highland Park, IL
john@chinet.chi.il.us
(312) 998-5007 (Day voice) || -432-8860 (Answer Mach) && -432-5386 Modem  

davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (08/23/89)

  In ksh you can do it using the uppercase attribute (I realize we don't
all use ksh yet).

	$ typeset -u ucase
	$ for file in *[a-z]*
	> do	ucase=${file}
	>	if [ ! -f $ucase ]
	>	then	mv ${file} ${ucase}
	>	else	echo "Can't move ${file}"
	>	fi
	>done

  ksh takes most of the pain out of it, although you may find typing in the
C program easier. If you have ksh you can put this in as a macro.

stevenw@oakhill.UUCP (Steven Weintraub) (08/23/89)

In article <9326@chinet.chi.il.us>, john@chinet.chi.il.us (John Mundt) writes:
> In article <20672@adm.BRL.MIL> Leisner.Henr@xerox.com (Marty) writes:
> >I'm looking for a good, clean way to move files from upper case names
> >to lower case names.
> >i.e. FOO.C to foo.c
> >I could always right a C program, but there gotta be a better way.

> #include <stdio.h>
> #include <ctype.h>
> 
> main()
> {
> 	register int c;
> 	while ((c = getchar()) != EOF)
> 		putchar(tolower(c));
> }

I should point out there is a risk in using tolower like this.  Some
machines define tolower as ((c)-'A'+'a') (like some sun systems).
This works well if the character is an upper case letter but it will
translate 'FOO.c' to 'fooN^C'.  Some things are never so easy.  I
thus use (for portability):

#define to_lower(c)  (isupper(c):tolower(c)?(c))

(of course this to fails if you send in *p++, UHG!!)

                   enough from this mooncalf - Steven
----------------------------------------------------------------------------
These opinions aren't necessarily Motorola's or Remora's - but I'd like to
think we share some common views.
----------------------------------------------------------------------------
Steven R Weintraub                             | O Lord,
...!cs.utexas.edu!oakhill!stevenw              |   let me talk gently,
Motorola Inc.  Austin, Texas                   | for I might have to eat my
(512) 891-3023 (office) (512) 453-6953 (home)  |   words tomorrow.
----------------------------------------------------------------------------

ag@cbmvax.UUCP (Keith Gabryelski) (08/24/89)

In article <9326@chinet.chi.il.us> john@chinet.chi.il.us (John Mundt) writes:
>In article <20672@adm.BRL.MIL> Leisner.Henr@xerox.com (Marty) writes:
>>I'm looking for a good, clean way to move files from upper case names to
>>lower case names.
>>
>>i.e. FOO.C to foo.c
>
>#include <stdio.h>
>#include <ctype.h>
>
>main()
>{
>	register int c;
>	while ((c = getchar()) != EOF)
>		putchar(tolower(c));
>}
>
>It's easier to write and compile this than to get tr to massage
>the string for you.  

Observe.

(the bourne shell)

$ for i in * ; do mv $i `echo $i | tr '[A-Z]' '[a-z]'` ; done

Or:

$ find . -type f -print | 
> while read filename
> do
>       mv $filename `echo $filename | tr '[A-Z]' '[a-z]'`
> done

Your code didn't solve any complex problem.  The only thing removed
from the above two commands is:

	tr '[A-Z]' '[a-z]'

and it would be replaced the name of the program you gave above (possibly
called 'mybrokentrwhichdoesnottakearguemnts' or maybe 'tolower').

On top of it all your solution would take compile time.

Pax, Keith
-- 
 "It took no computation to dance to the rock 'n roll station" -- Lou Reed
  ag@cbmvax.commodore.com     Keith M. Gabryelski      ...!uunet!cbmvax!ag

guy@auspex.auspex.com (Guy Harris) (08/24/89)

>It's easier to write and compile this than to get tr to massage
>the string for you.  

Well, maybe, but I really tend to doubt it.  The algorithm for finding
the right "tr" command is:

	if (you have S3 or S5 (or V6?))
		use the command

			tr '[A-Z]' '[a-z]'

	else /* you have V7 or 2.xBSD or 4.xBSD */
		use the command

			tr 'A-Z' 'a-z'

which strikes *me* as being easier than typing in and compiling said
program (fewer characters, for one thing!).

And there's even an optimization; given the way the V7/2.xBSD/4.xBSD
"tr" parses its arguments, the command

	tr '[A-Z]' '[a-z]'

will do the right thing (it will translate '[' to '[' and ']' to ']', as
well as translating upper-case letters to lower-case letters; this trick
does *not* work in general, though, since '[' and ']' don't have special
meaning to the V7/2.xBSD/4.xBSD "tr").

In either case, of course, you have to feed the file names to this
program, extract the file names out the other end, and use them in an
"mv" command, which strikes me as more work than just getting the
translation done.  Once you've gotten the list of file names, I would be
tempted to try:

	for i in <the list>	# note - <the list> is not to be typed
				# literally; it's the list of file names
	do
		mv $i `echo $i | <the command>`
	done

where <the command> is the "tr" command in question (or, if you're
really insistent, the case-translation program supplied).  (Said "for"
construct is, of course, a Bourne shell construct, so if your login
shell is the C shell you'd either have to 1) use the C shell equivalent
or 2) type "sh" before typing in the construct; the C shell equivalent
is left as an exercise for the reader.)

sean@watcsc.waterloo.edu (Sean Goggin) (08/24/89)

In article <20672@adm.BRL.MIL> Leisner.Henr@xerox.com (Marty) writes:
>I'm looking for a good, clean way to move files from upper case names to lower 

Easy use sh or /bin/sh and do the following

for i in *
>do
>mv $i `echo $i | tr "[A-Z]" "[a-z]"`
>done

the wildcard on the top is of course the files.
TEST this first, it should run on all things, but who knows, eh.

Sean Goggin 
_______________________________________________________________________________
 |o| HAL 9000 / SAG         S Goggin  BITNET -  bvscistu@watdcs.bitnet
_|_|__________________________________UUCP___-_...!watmath!watcsc!sean_________

john@chinet.chi.il.us (John Mundt) (08/24/89)

In article <2336@oakhill.UUCP> stevenw@oakhill.UUCP (Steven Weintraub) writes:
>> 	while ((c = getchar()) != EOF)
>> 		putchar(tolower(c));
>I should point out there is a risk in using tolower like this.  Some
>machines define tolower as ((c)-'A'+'a') (like some sun systems).
>This works well if the character is an upper case letter but it will
>translate 'FOO.c' to 'fooN^C'.

Are you sure that tolower() and _tolower() aren't being confused?  The
latter is a macro that just takes a value and |= 040 to it to make it
lower case, since it requires that an upper case letter be sent to it.

tolower(), on the other hand, is a function that firsts checks to see if
the value sent to it is uppercase, and only then does it do anything.

Quoting from the man page, 

"..tolower has as a domain the rainge of getc(3S):  the integers from
-1 to 255.  If the argument of tolower represents an 
upper-case letter, the result is the corresponding lower-case letter.
All other arguments in the domain are returned unchanged."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


-- 
---------------------
John Mundt   Teachers' Aide, Inc.  P.O. Box 1666  Highland Park, IL
john@chinet.chi.il.us
(312) 998-5007 (Day voice) || -432-8860 (Answer Mach) && -432-5386 Modem  

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/26/89)

In article <9346@chinet.chi.il.us> john@chinet.chi.il.us (John Mundt) writes:
>Quoting from the man page, 

Really, you should know better than this.  "The" man page??  There are
many variants of UNIX; as the fellow you were responding to clearly
indicated, some of them currently supply toupper() functions that operate
differently from the way you cited.

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (08/29/89)

? From: Guy Harris <guy@auspex.auspex.com>

? >It's easier to write and compile this than to get tr to massage
? >the string for you.  

? Well, maybe, but I really tend to doubt it.  The algorithm for finding
? the right "tr" command is:

[algorithm deleted -- it should be correct given Guy's knowledge]

? And there's even an optimization; given the way the V7/2.xBSD/4.xBSD
? "tr" parses its arguments, the command

? 	tr '[A-Z]' '[a-z]'

? will do the right thing (it will translate '[' to '[' and ']' to ']', as
? well as translating upper-case letters to lower-case letters; this trick
? does *not* work in general, though, since '[' and ']' don't have special
? meaning to the V7/2.xBSD/4.xBSD "tr").

Interesting point.

Yeah, but what about that stupid null-eating property of tr?
Any plans to fix it? Maybe with an option? TR needs more feechurs :-)

	Root Boy Jim
	Have GNU, Will Travel.

rbj@dsys.ncsl.nist.gov (Root Boy Jim) (08/29/89)

OOPS! Of course, in filenames, null's never appear. However, in the
general case, I find tr's null-eating propertys distasteful.

	Root Boy Jim
	Have GNU, Will Travel.