[comp.unix.wizards] HELP converting filenames!

david@pyr.gatech.EDU (David Brown) (09/28/89)

Hiya.  I have a friend who has about 200 files in a directory that are all
upper case.  They are data files that need to be in lower case, because
his brain-dead program won't recognize upper case letters.  It's a i386
box, running some form of Xenix, but he doesn't have the development system.
Can any of you Bourne shell or C-shell wizards out there tell me how to
write a script that will convert them?  He's VERY anxious to get them
converted (he's almost dead in the water until he does).

PLEASE E-mail me anything you think might help!

Thanks,
  David Brown

-- 
David Brown                       Armstrong State College, Savannah, Georgia
ARPA: david@pyr.gatech.edu        uucp: ...!gatech!gitpyr!david

steve@nuchat.UUCP (Steve Nuchia) (09/28/89)

In article <9234@pyr.gatech.EDU> david@pyr.gatech.edu (David Brown) writes:
>Hiya.  I have a friend who has about 200 files in a directory that are all
>upper case.  They are data files that need to be in lower case, because
>his brain-dead program won't recognize upper case letters.  It's a i386

With friends like these, who needs VM/CMS?


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

or in csh

foreach x (*)
mv $x `echo $x | tr A-Z a-z`
end

I didn't bother getting all the syntactic details right on the
tr calls, they differ from version to version anyway.  Test the
syntax by replacing mv with echo until you are satisfied with
the $x, f($x) pairs it prints, then do it for real.
-- 
Steve Nuchia	      South Coast Computing Services
uunet!nuchat!steve    POB 270249  Houston, Texas  77277
(713) 964 2462	      Consultation & Systems, Support for PD Software.

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (09/29/89)

In article <15058@nuchat.UUCP> steve@nuchat.UUCP (Steve Nuchia) writes:
: In article <9234@pyr.gatech.EDU> david@pyr.gatech.edu (David Brown) writes:
: >Hiya.  I have a friend who has about 200 files in a directory that are all
: >upper case.  They are data files that need to be in lower case, because
: >his brain-dead program won't recognize upper case letters.  It's a i386
: 
: With friends like these, who needs VM/CMS?
: 
: 
: for x in *
: do mv $x `echo $x | tr A-Z a-z`
: done
: 
: or in csh
: 
: foreach x (*)
: mv $x `echo $x | tr A-Z a-z`
: end

Or, more efficiently, if you have the rename perl script handy:

	rename y/A-Z/a-z/ *

For those who missed it, here's a simple version of the script:

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

The first argument is any old perl expression that modifies $_.
So you can do commands like:

	rename 's/\.orig$//' *.orig
	rename 'y/A-Z/a-z/ unless /^Make/' *
	rename '$_ .= ".bad"' *.f
	rename 'print "$_: "; s/foo/bar/ if <stdin> =~ /^y/i' *

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov

merlyn@iwarp.intel.com (Randal Schwartz) (10/03/89)

In article <9234@pyr.gatech.EDU>, david@pyr (David Brown) writes:
| 
| Hiya.  I have a friend who has about 200 files in a directory that are all
| upper case.  They are data files that need to be in lower case, because
| his brain-dead program won't recognize upper case letters.  It's a i386
| box, running some form of Xenix, but he doesn't have the development system.
| Can any of you Bourne shell or C-shell wizards out there tell me how to
| write a script that will convert them?  He's VERY anxious to get them
| converted (he's almost dead in the water until he does).

Yeah, in Perl, it'd be:

for $old (<*>) {
	($new = $old) =~ y/A-Z/a-z/;
	rename($old,$new) || warn "Cannot rename $old to $new ($!)";
}

But, if you don't have Perl (shame on you!), here's the /bin/sh (et. al.)
solution:

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

Of course, with this solution, you are firing off four processes for
each file, but it still works.  Might take a while for 200 names.

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!" ==/

rusty@cadnetix.COM (Rusty Carruth) (10/06/89)

In article <5003@omepd.UUCP> merlyn@iwarp.intel.com (Randal Schwartz) writes:
>In article <9234@pyr.gatech.EDU>, david@pyr (David Brown) writes:
>| 
>| Hiya.  I have a friend who has about 200 files in a directory that are all
>| upper case.  They are data files that need to be in lower case, because
>| his brain-dead program won't recognize upper case letters.  
>
>Yeah, in Perl, it'd be:
>...
>But, if you don't have Perl (shame on you!), here's the /bin/sh (et. al.)
>solution:
>
<solution requiring 'tr'>
>
Of course, if all else fails, do my favorite trick which I use
whenever all else fails.  Make a script.

First, go to the directory of interest and do 'ls -1 > doit'.
Chmod 777 doit. Now, go edit 'doit' (for all you emacs haters
out there, sorry but emacs seems to work better for what I'm about
to suggest than does vi) and make a macro (sorry folks, this
trick will pretty much require emacs) which adds a space or two
to the end of the current line and then copies that line to its
end (making a line like 'file' end up as 'file  file  ' - If
you have a problem with the trailing space, make the macro
a bit different), and then changes the added information to
all lower case, then goes to the next line.  Now, execute 
that macro 200 times.  Now go back and add the 'mv' command to
the front of each line (another macro).  Don't forget
your #!/bin/csh (or sh), close and save, execute it,
and you are done.

And you could have moved them to another directory in the
process (or every other one to a different dir...) had you
wanted to.

not as elegant as the other solutions?  Sure.  But it
will get the job done.
---Join the usenet un-net, 28.410 and/or 28.390, 1500Z to 1600Z saturdays!
Rusty Carruth.                  Radio: N7IKQ              ^^ or later :-)  
DOMAIN: rusty@cadnetix.com      UUCP:{uunet,boulder}!cadnetix!rusty   
home: POB. 461, Lafayette 80026

amos@taux01.UUCP (Amos Shapir) (10/07/89)

In article <9754@cadnetix.COM> rusty@cadnetix.COM (Rusty Carruth) writes:
|
|First, go to the directory of interest and do 'ls -1 > doit'.
|Chmod 777 doit. Now, go edit 'doit' (for all you emacs haters
|out there, sorry but emacs seems to work better for what I'm about
|to suggest than does vi) and make a macro (sorry folks, this
|trick will pretty much require emacs) which adds a space or two
|to the end of the current line and then copies that line to its
|end (making a line like 'file' end up as 'file  file  ' - If
|you have a problem with the trailing space, make the macro
|a bit different), and then changes the added information to
|all lower case, then goes to the next line.  Now, execute 
|that macro 200 times.  Now go back and add the 'mv' command to
|the front of each line (another macro).

What?  You have to do all that in emacs, and you still claim it's
better than vi?  To save vi's lost honor, here's how it should be done:

:%s/.*/mv & \U&\e/

One line, no macros needed.
-- 
	Amos Shapir		amos@taux01.nsc.com or amos@nsc.nsc.com
National Semiconductor (Israel) P.O.B. 3007, Herzlia 46104, Israel
Tel. +972 52 522261  TWX: 33691, fax: +972-52-558322
34 48 E / 32 10 N			(My other cpu is a NS32532)

tchrist@convex.COM (Tom Christiansen) (10/07/89)

In article <9754@cadnetix.COM> rusty@cadnetix.COM (Rusty Carruth) writes:
|In article <5003@omepd.UUCP> merlyn@iwarp.intel.com (Randal Schwartz) writes:
|>In article <9234@pyr.gatech.EDU>, david@pyr (David Brown) writes:
|>| 
|>| Hiya.  I have a friend who has about 200 files in a directory that are all
|>| upper case.  They are data files that need to be in lower case, because
|>| his brain-dead program won't recognize upper case letters.  
|>
|>Yeah, in Perl, it'd be:
|>...
|>But, if you don't have Perl (shame on you!), here's the /bin/sh (et. al.)
|>solution:

I second the "shame on you"; lwall's rename script posted in reponse to
this subject thread was the most powerful, yet small and elegant, such 
thing that the I've ever seen.  The day I compiled perl was my last
day of writing disgusting sed/awk/tr/sort/sh monstrosities.

|Of course, if all else fails, do my favorite trick which I use
|whenever all else fails.  Make a script.
|
|First, go to the directory of interest and do 'ls -1 > doit'.
|Chmod 777 doit. Now, go edit 'doit' (for all you emacs haters
|out there, sorry but emacs seems to work better for what I'm about
|to suggest than does vi) and make a macro (sorry folks, this
|trick will pretty much require emacs) which adds a space or two
|to the end of the current line and then copies that line to its
|end (making a line like 'file' end up as 'file  file  ' - If
|you have a problem with the trailing space, make the macro
|a bit different), and then changes the added information to
|all lower case, then goes to the next line.  Now, execute 
|that macro 200 times.  Now go back and add the 'mv' command to
|the front of each line (another macro).  Don't forget
|your #!/bin/csh (or sh), close and save, execute it,
|and you are done.

Shame on *you* for spreading the Black Legend that vi isn't up 
to this kind of thing.  The easiest way to do it is like this
(after directing your ls into a file and calling ex or vi on it):

:%s/.*/mv & \L&/

but you CAN write a macro for it.  for example, here is a centering macro:
(all these have been run through 'cat -v' to quote control characters)

map v $ma81a ^V^[81^V|D`ald0:s/  / /g^V^M$p

which is a better way to do the more convoluted:

map v :co.^V^Mk:s/./ /g^V^Mo^V^[80a ^V^[:-1s;.*;:s/&//;^V^M"mdd@m:s/../ /g^V^MJ

which is a better way to do the still more convoluted:

map v o^V^[k:co.^V^M:s/./ /g^V^Mo^V^[80a ^V^[:-1s;^;:s/;^V^M:s;$;//;^V^M"mdd@m:s/\(.\)./\1/g^V^M:s;^;:-1s/^/;^V^M"mdd@mjdd

The more complicated examples make use of buffer execation (eg. @a).  In
developing more elaborate macros or substitutes (like those with \(...\)
constructions in them), I often type the line in by hand and then yank it
into a buffer and execute the buffer.  That way if it fails, you can just
edit the line and try again.  You'll find that if you execute a buffer with
:map in it that you may need one more level of quoting via ^V than you 
would from your startup file.  Thus the above maps work as written from
your .exrc but if executed out of a buffer, they need doubled ^V's. 

You can also write mutually recursive macros.

I append my current map set from my .exrc for the stout of heart.
read the comments here for descriptions of what they do.  Some
of these may have extra ^V's cause they were developed using the buffer
execution method, but it doesn't seem to hurt anything when read
from the .exrc file. Yes, some of the macros define their own new
macros.

The "meta-key" I use to get at all the \c things is either tab OR backslash
depending on the whims of my fingers.

The lint and commenting macros are possibly the neatest things here.


"----- start of .exrc, after munging control characters w/ "cat -v"
"
"	INPUT MACROS that i always want active
"
map! ^Z ^[:stop^M
"	so i can stop in input mode.  note that autowrite is set, so 
map! ^A ^[:stop!^M
"	will stop me without writing.
"
map! ^K ^V^[O
"	lets me do kindof a negative carriage return in input mode.
map! ^B ^[bi
"	non-destructive ^W
map! ^F ^[Ea
"	and its inverse
"
"	ARROW MACROS next four let arrows keys work in insert mode; 
map! ^V^[OD ^V^[i
map! ^V^[OB ^V^[ja
map! ^V^[OA ^V^[ka
map! ^V^[OC ^V^[lli
"
"
"	EXCHANGE MACROS -- for exchanging things
"
map v xp
"	exchange current char with next one in edit mode
map V :m+1^M
"	exchange current line with next one in edit mode
map! ^P ^V^[hxpa
"	exchange last typed char with penultimate one in insert mode
map = ^^
"	edit previously editted file
"
"
"
"	other macros
"
map g G
"	because it's easier to type
map ^A :stop!^M
"	unconditional stop
map ' `
"	so we return to exact position, not just ^ on 'a or ''
map Y y$
"	so Y is analagous to C and D
map ^R ddu
"	single-line redraw
map ^N :n +/^M
"	go to next file in arg list, same position 
"	useful for "vi +/string file1 file2 file3"
"
"
"	META MACROS, all begin with meta-key '\' ; more later in file
"
map ^V	 \
"	so can use both ^I and \ for meta-key
"
map \\ i^M^[
"	split line
"
map \/ dePo/\<^V^[pA\>^V^["wdd@w
"	find current word, uses w buffer
"
map \w :w^M
"	write out the file
"
map \C $ma81a ^V^[81^V|D`ald0:s/  / /g^V^M$p
"	center text
"
"	EXECUTION MACROS --	these two are for executing existing lines.  
"
map \@ ^V^["mdd@m
map \2 \@
"	xqt line as a straight vi command (buffer m, use @@ to repeat)
map \! 0i:r!^V^["ndd@n
map \1 \!
"	xqt line as :r! command (buffer n, use @@ to repeat)
"	
"
"	BLOCK MACROS -- these make { and } hot keys in insert mode
"
map! ^O ^V^V^V{^M^V^V^V} ^V^[O^T
"	this will begin a block, leaving in insert mode
map! ^] ^V^[/^V^V^V}^V^Ma
"	and this  will take you past its end, leaving in insert mode
"
"
"
"	LINT MACRO.  deletes all text from "lint output:" and below, (if any)
"	replacing it with lint output in pretty block comment form.  could
"	do sed work myself, but this is faster.  
"
"	the map! is for subsequent map, not by people, 
"	tho /^Lo would make sense.
"	this is one of those famous time/space tradeoffs 
map! ^Lo lint output
"
"	and now for the real work
map \l Go^M/* ^Lo^M^[/^Lo^MdG:w^Mo/*** ^Lo^[<<:r!lint -u -lc %^V|sed 's/^/ *  /'^MGo***/^[N
"
"	indent this for me
"
map \i :%!indent -i4^M
"
"	COMMENTING MACROS -- these are actually pretty amazing
"
"	from edit mode, this comments a line
map ^X ^i/* ^[A */^[^
"
"	and this undoes it
map ^Y :s/\/\* \([^*]*\) \*\//\1^[
"
"	this next one defeats vi's tail-recursion defeatism
"	called by 2 maps following this one 
map! ^N ^V^[:unmap! ^V^V^M^[
"
"	while in insert mode, this will put you "inside" a comment
map! ^X ^V^[:map! ^V^V^M ^V^V^[a^V^V^V^No^[a /*  */^[hhi
"
"	while in edit mode, this begins a block comment -- ^N to escape
"	looking quite like this:
"	/*
"	 *  (you are here)
"	 */
"	(you were here)
map \c	O/*^M *  ^M*/^[k:map! ^V^V^M ^V^V^M*  ^MA
"
"	and this is for adding more lines to a block comment -- ^N to escape
map \o	:map! ^V^V^M ^V^V^M*  ^MA
"
"----- end of .exrc, after munging control characters w/ "cat -v"


So remember: 
    To a true hacker, all things are possible, but not all expedient. :-)


--tom

    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist@convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"

dhesi@sun505.UUCP (Rahul Dhesi) (10/08/89)

In article <1983@convex.UUCP> tchrist@convex.COM (Tom Christiansen) writes:
>I second the "shame on you"; lwall's rename script posted in reponse to
>this subject thread was the most powerful, yet small and elegant, such 
>thing that the I've ever seen.

#! /bin/sh
# converts filenames to lowercase without zapping mixed-case names
# -- Rahul Dhesi, Oct 1989
# (powerless, big-gish, inelegant, but *portable-ish*)
for f in "$@"
do
   case "$f" in
   *[a-z]*)
      #echo "skipping $f, contains lowercase chars"
      ;;
   *)
      newname=`echo "$f" | tr 'A-Z' 'a-z'`
      if test "$newname" != "$f"
      then
         if test -f "$newname"
         then
            echo "$newname already exists"
         else
            mv "$f" "$newname"
         fi
      fi
      ;;
   esac
done

By the way, those intellectually inclined may want to find the one
significant remaining bug in the above script.

Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

les@chinet.chi.il.us (Leslie Mikesell) (10/08/89)

In article <2694@taux01.UUCP> amos@taux01.UUCP (Amos Shapir) writes:
>|First, go to the directory of interest and do 'ls -1 > doit'.
[...emacs conversion of "FILENAME" to "mv FILENAME filename"]

>What?  You have to do all that in emacs, and you still claim it's
>better than vi?  To save vi's lost honor, here's how it should be done:

>:%s/.*/mv & \U&\e/
>One line, no macros needed.

And, of course, you can read the original filenames in with:
:r !ls
and execute the commands in the edited buffer with:
:w !sh

No temporary files needed.

Les Mikesell 

amos@taux01.UUCP (Amos Shapir) (10/10/89)

Since we are at it, here are some useful macros for spell checking
out of my own grab bag:

(I map them to function keys 1-3; of course you can change it to any
 other unused key)

" Use the 4 letters starting at the cursor as a word to look up
" in the standard 'look' dictionary.
:map #1 4y O!look ^[p"xdd:@x^[

" Run the current file through spell, and put the resulting list of
" misspelled words at the end of the file.
:map #2 :$r!spell %^[

" Now do 'G' and start looking over the list; for each word, either
" do 'dd' if it's irrelevant, or do 'F3' to put the cursor on it.
:map #3 I/\<^[A\>^["xdd:@x^[n

" An 'n' will take you to the next occurrence of the same word.  When
" you're through with it, do a 'G' to look at the next one.

-- 
	Amos Shapir		amos@taux01.nsc.com or amos@nsc.nsc.com
National Semiconductor (Israel) P.O.B. 3007, Herzlia 46104, Israel
Tel. +972 52 522261  TWX: 33691, fax: +972-52-558322
34 48 E / 32 10 N			(My other cpu is a NS32532)

dg@lakart.UUCP (David Goodenough) (10/11/89)

From article <2694@taux01.UUCP>, by amos@taux01.UUCP (Amos Shapir):
> In article <9754@cadnetix.COM> rusty@cadnetix.COM (Rusty Carruth) writes:
> |
> |First, go to the directory of interest and do 'ls -1 > doit'.
> |Chmod 777 doit. Now, go edit 'doit' (for all you emacs haters
> |out there, sorry but emacs seems to work better for what I'm about
> |to suggest than does vi) .....

long discourse on emacs use deleted

> What?  You have to do all that in emacs, and you still claim it's
> better than vi?  To save vi's lost honor, here's how it should be done:
> 
> :%s/.*/mv & \U&\e/
> 
> One line, no macros needed.

I'd agree with Amos, except why not do the following:

foreach i ( filelist )
mv $i `echo $i | tr a-z A-Z`
end

(or if you still live in the dark ages)

for i in filelist
do
mv $i `echo $i | tr a-z A-Z`
done
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com			  +---+

rml@hpfcdc.HP.COM (Bob Lenk) (10/11/89)

Having seen a few postings with lines like:

>	mv $old `echo $old | tr A-Z a-z`

I thought it worth pointing out that tr syntax is different in BSD and
SysV systems.  In System V this command line will only convert A and Z
characters to lower-case, leaving B-Y untouched.  The SysV (and POSIX.2
Draft 9) syntax is

	mv $old `echo $old | tr '[A-Z]' '[a-z]'`

While I'm at it, note that both SysV and BSD echo will do strange
things with certain filenames ( -n for BSD, names with backslashes
for SysV).  This can be avoided with a here-document.

		Bob Lenk
		rml@hpfcla.hp.com
		hplabs!hpfcla!rml

allbery@NCoast.ORG (Brandon S. Allbery) (10/13/89)

As quoted from <9754@cadnetix.COM> by rusty@cadnetix.COM (Rusty Carruth):
+---------------
| In article <5003@omepd.UUCP> merlyn@iwarp.intel.com (Randal Schwartz) writes:
| >In article <9234@pyr.gatech.EDU>, david@pyr (David Brown) writes:
| >| Hiya.  I have a friend who has about 200 files in a directory that are all
| >| upper case.  They are data files that need to be in lower case, because
| >| his brain-dead program won't recognize upper case letters.  
| >
| <solution requiring 'tr'>
| 
| First, go to the directory of interest and do 'ls -1 > doit'.
| Chmod 777 doit. Now, go edit 'doit' (for all you emacs haters
| out there, sorry but emacs seems to work better for what I'm about
| to suggest than does vi) and make a macro (sorry folks, this
| trick will pretty much require emacs) which adds a space or two
+---------------

Nonsense.

vi:	:1,$s/.*/mv & &/
emacs:	M-X replace-regexp RET ^.*$ RET mv \& \& RET

You did, however, forget to switch the case on the second copy.

My usual way of doing it:

ls | sed 'h;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;x;G;s/\n/ /;s/^/mv /' | sh

(Usually, I do this twice, the first time with "echo" instead of "mv", so I
can make sure I didn't blow it.  I just tested this, BTW; it works fine under
Xenix.  Other OSes may vary, but it should work under standard System V's.)

++Brandon
-- 
Brandon S. Allbery, moderator of comp.sources.misc	     allbery@NCoast.ORG
uunet!hal.cwru.edu!ncoast!allbery		    ncoast!allbery@hal.cwru.edu
bsa@telotech.uucp, 161-7070 BALLBERY (MCI), ALLBERY (Delphi), B.ALLBERY (GEnie)
Is that enough addresses for you?   no?   then: allbery@uunet.UU.NET (c.s.misc)

tony@oha.UUCP (Tony Olekshy) (10/14/89)

In message <9754@cadnetix.COM>, rusty@cadnetix.COM (Rusty Carruth) writes:
|
|   [A supposed solution that works better with emacs than vi]
|
| First, go to the directory of interest and do 'ls -1 > doit'.  Chmod 777
| doit.  Now, go edit 'doit' and make a macro  which adds a space to the end
| of the current line and then copies that line to its end (making a line
| like 'file' end up as 'file file '), and then changes the added information
| to all lower case, then goes to the next line.  Now, execute that macro 200
| times. Now go back and add the 'mv' command to the front of each line
| (another macro).  Don't forget your #!/bin/csh (or sh), close and save,
| execute it, and you are done.

Oh blecch...	vi			# Edit *no* file.
		!!ls -1			# Get list of files to move.
		:%s/.*/mv & \L&/	# Build mv to lower-case.
		1G!Gsh -x		# Run mv commands.
		:q!			# Don't save *no* file.

--
Yours, etc., Tony Olekshy (...!alberta!oha!tony or tony@oha.UUCP).