[comp.unix.questions] Changing upper-case filenames to lower-case

kfink@jarthur.Claremont.EDU (Kevin Fink) (11/18/89)

Is there an easy way to change all the upper-case characters in a filename
(or set of filenames) to lower-case?

Whenever I transfer files from my PC to the mainframe the filenames get
changed to all caps. This is really annoying.

Thanks.

Kevin Fink

dbin@norsat.UUCP (Dave Binette) (11/19/89)

:
# loname
# convert uppercase names to lowercase
for i in $*
do
	L=`echo $i|tr "[A-Z]" "[a-z]"`
	echo $i $L
	mv $i $L
done
-- 
"If I was smarter than I was bad, I wouldn't get in any trouble" (Laura 4yrs.)
uucp:  {uunet,ubc-cs}!van-bc!norsat!dbin | 302-12886 78th Ave
bbs:   (604)597-4361     24/12/PEP/3     | Surrey BC CANADA
voice: (604)597-6298     (Dave Binette)  | V3W 8E7

merlyn@iwarp.intel.com (Randal Schwartz) (11/22/89)

In article <3116@jarthur.Claremont.EDU>, kfink@jarthur (Kevin Fink) writes:
| Is there an easy way to change all the upper-case characters in a filename
| (or set of filenames) to lower-case?
| 
| Whenever I transfer files from my PC to the mainframe the filenames get
| changed to all caps. This is really annoying.

Deja vu.  Didn't we just answer this one?

The solution in Perl:

perl -e 'for$f(<*>){($_=$f)=~y/A-Z/a-z/;rename($f,$_)unless$f eq$_;}'

The solution in sh, tr, echo:

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

There.  Isn't this in the FAQ list?

Just another Perl hacker,
-- 
/== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\
| on contract to Intel's iWarp project, Hillsboro, Oregon, USA, Sol III  |
| merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn	         |
\== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/

chip@ateng.com (Chip Salzenberg) (11/30/89)

According to merlyn@iwarp.intel.com (Randal Schwartz):
>perl -e 'for$f(<*>){($_=$f)=~y/A-Z/a-z/;rename($f,$_)unless$f eq$_;}'

I'd think that "<*>", which runs "/bin/sh echo", should be avoided.
Rather, you'd be better off reading the directory directly...

	eval 'exec /bin/perl -S $0 ${1+"$@"}'
		if 0;
	
	# Get all the files' names
	opendir(DOT,".") || die "$0: can't read \".\": $!\n";
	@F = readdir(DOT);
	closedir(DOT);
	@F = sort @F;
	
	# Rename some of them
	foreach $f (@F) {
		next if $f =~ /^\./;    # Don't mess with invisible files
		($_ = $f) =~ y/A-Z/a-z/;
		rename($f, $_) unless $f eq $_;
	}

Yet Another Perl Hacker,
-- 
You may redistribute this article only to those who may freely do likewise.
Chip Salzenberg at A T Engineering;  <chip@ateng.com> or <uunet!ateng!chip>
	  "The Usenet, in a very real sense, does not exist."

lee@sq.sq.com (Liam R. E. Quin) (12/07/89)

In article <25747F32.4268@ateng.com> chip@ateng.com (Chip Salzenberg) writes:
>According to merlyn@iwarp.intel.com (Randal Schwartz):
>>perl -e 'for$f(<*>){($_=$f)=~y/A-Z/a-z/;rename($f,$_)unless$f eq$_;}'

>I'd think that "<*>", which runs "/bin/sh echo", should be avoided.
>[much longer solution deleted]

Er, am I missing something?

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

If you only want to move some of the files, change * to `pick *` (if you
have pick -- see ``The Unix Programming Environment'' (Kernighan & Pike)
for the source to pick if you don't)
If you also want to rename files that begin with a dot, replace the * with
`ls -a`, and use `find . -type f -print` to include files in subdirectories
and exclude subdirectories...

Is the issue really minimising the number of characters typed, getting the
most easily understood solution, or simply doing as much as possible in perl?
Do you get brownie points for the most cryptic perl one-liner?  0.5 :-)

Incidentally, one common way of getting lots of files in upper case on a
386 Unix system is by using some of the "dosget" or "doscp" programs.
In this case, it's worth writing a simple script that takes the output of
"dosdir" or "dosls" and generates a sequence of commands that copy the
files into lower case names.  Some versions of "dosget" have an option to
do this.

Lee
-- 
Liam R. Quin, Unixsys (UK) Ltd [note: not an employee of "sq" - a visitor!]
lee@sq.com (Whilst visiting Canada from England, until Christmas)
 -- I think I'm going to come out at last...
 -- What?  Admit you're not a fundamentalist Jew?  They'll *crucify* you!  :-)

tale@cs.rpi.edu (Dave Lawrence) (12/07/89)

According to merlyn@iwarp.intel.com (Randal Schwartz):
RandalL> perl -e 'for$f(<*>){($_=$f)=~y/A-Z/a-z/;rename($f,$_)unless$f eq$_;}'

In article <25747F32.4268@ateng.com> chip@ateng.com (Chip Salzenberg) writes:
Chip> I'd think that "<*>", which runs "/bin/sh echo", should be avoided.
Chip> [much longer solution deleted]
 
In <1989Dec7.020047.8178@sq.sq.com> lee@sq.sq.com (Liam R. E. Quin) writes:
Liam> Er, am I missing something?

Yes.

Liam> for i in *
Liam> do
Liam>   mv $i `echo $i | tr '[A-Z]' '[a-z]'`
Liam> done
 
Fine.  I have a directory with 400 files in it that I want to convert
this way.  You just soaked up 800 processes.  The perl solution used
two (that is, as long as Chip is right about the /bin/sh, and I don't
have any reason to doubt him).  Depending on the limitations of your
sh, too, the * expansion might break in both your version and the
original perl example.

Liam> Is the issue really minimising the number of characters typed,
Liam> getting the most easily understood solution, or simply doing as
Liam> much as possible in perl?

RandalL offered the perl solution both to continue his presence as the
man who can make perl do anything but buy him dinner and to show an
efficient way of handling multiple files, since perl uses the unlink(2)
call directly.

Chip followed up on RandalL's efficiency offering by not only doing
the unlink() calls from perl, but the reading of the directory file
too.  This puts it into one process, no matter the size of the
directory.

Both RandalL's and Chip's messages were pretty clear about why they
were being offered.

Dave
-- 
   (setq mail '("tale@cs.rpi.edu" "tale@ai.mit.edu" "tale@rpitsmts.bitnet"))

jimr@hp-lsd.COS.HP.COM (Jim Rogers) (01/05/90)

I was surprised that no one came up with the simple and efficient ksh
answer to this:


#!/bin/ksh
typeset -i flag
(( flag = 0 ))
set -- `getopt du $*`
for i in $*
do
	case $i in
	-d)	typeset -l nf; (( flag = 1 )); shift;;
	-u)	typeset -u nf; (( flag = 1 )); shift;;
	--)	shift; break;
	esac
done
if (( flag == 0 ))
then
	typeset -l nf
fi
while [ $# -gt 0 ]
do
	nf=${1}
	if [ "$nf" != "$1" ]
	then
		print "Do you want to convert ${1} to ${nf} (Y/N)?"
		read
		if [ "$REPLY" = "Y" -o "$REPLY" = "y" ]
		then
			print "Moving ${1} to ${nf}"
			mv ${1} ${nf}
		fi
	fi
	shift
done


This version will shift up or down as you please.
To shift up use the "-u" option.
To shift down either use the "-d" option or no option.


Jim Rogers