[ale] scripting (looping through filenames containing spaces)

Gary Maltzen maltzen at mm.com
Wed Jul 5 11:23:16 EDT 2000


Of course, immediately after I sent the message it dawned on me that you
should bracket the 'mv' with an 'if' to protect against renaming over an
existing file.

It also dawned on me that you might inadvertently have the procedure in the
path you were lowercasing...

Later it dawned on me that you could do both files AND directories in one
pass using the depth-first option of find. Ergo

  find ${base} -name '*[A-Z]*' -depth -exec lowercase \{\} \;

where 'lowercase' shell script contains

  #!/bin/bash
  # PN=pathname BN=basename 1=before 2=after
  PN1=$*
  BN1=`basename "${PN1}"`
  BN2=`echo "${BN1}" | tr '[A-Z]' '[a-z]'`
  PN2=`echo "${PN1}" | sed -e "s/${BN1}\$/${BN2}/"`
  # rename PN1 to PN2 only if PN2 doesn't already exist
  if [ ! -e "${PN2}" ] then
    mv -i "${PN1}" "${PN2}"
  fi

> The principal problem is to rename ONLY the last component name of the
filepath; the secondary problem is to not rename directories in mid-search.
>
> Rather than having 'find' just create a list upon which you operate, why
not have 'find' invoke a procedure for each found file, something like...
>
> 1) lowercase all the non-directory filenames
>
>     find $base -name '*[A-Z]*' -not -type d -exec LOWER \{\} \;
>
> 2) lowercase all the directory names
>
>     find $base -name '*[A-Z]*' -type d -exec LOWER \{\} \;
>
> 3) a (LOWER) procedure to lowercase the final component filename
>
>     #!/bin/bash
>     #
>     # PN1 - original pathname "/Path/To/Some File"
>     # BN1 - original basename "Some File"
>     # BN2 - modified basename "some file"
>     # PN2 - modified pathname "/Path/To/some file"
>     #
>     PN1=$*
>     BN1=`basename "${PN1}"`
>     BN2=`echo "${BN1}" | tr '[A-Z]' '[a-z]'`
>     PN2=`echo "${PN1}" | sed -e "s/${BN1}\$/${BN2}/"`
>     mv -i "${PN1}" "${PN2}"
>
> Note that the quotes around PN1 and PN2 are necessary to accomodate
embedded spaces.
>
> To test this, change the final line of LOWER to
>
>     echo mv -i \"${PN1}\" \"${PN2}\"
>
> At 11:35 PM 7/3/2000 , Ben Phillips said...
> >SHORT STORY:
> >
> >Fix the script below so it outputs the following:
> >
> >a b c
> >1 2 3
> >
> >It's important that the backquotes (or some other command-substition) be
> >there.  The idea is to get 'for' to recognize tokens that have whitespace
> >characters in their names.
> >
> >------------------------------------------
> >#! /bin/bash
> >#
> ># Loop through output that contains spaces
> >#
> >
> >  for i in `echo \"a b c\"; echo \"1 2 3\"`;
> >     do echo $i
> >  done
> >------------------------------------------
> >
> >
> >
> >LONG STORY:
> >
> >Yesterday I determined I was tired of having capital letters in the names
of
> >the files on my Windows partition.  (Don't laugh.)
> >
> >So I tried to use 'find' and a 'for' loop to change the names of all the
> >directories (thinking I'd do the filenames later).  And then I realized
that
> >'for' just wasn't cut out to deal with tokens that have spaces in them;
it
> >thinks a directory named "TWO WORDS" is really two items named TWO and
> >WORDS, and it treats them that way even when I encase them in quotes.  (I
> >even wrote a bit of perl that will encase each line of output in
> >double-quotes, so my script is taking in a list just like the above
example.
> >Tried it with single-quotes, too, to no avail.)
> >
> >Any alternatives you can suggest for accomplishing the same thing would
be
> >much appreciated.
> >
> >Here's the full script as I have it so far; please feel free to nitpick
my
> >scripting style.
> >
> >
> >#!/bin/bash
> >#
> ># Recursively lower-case the name of every directory in a tree
> ># (The perl lines are just encasing every line of input in quotes.)
> >#  \x22 == double quote; \x27 == single quote
> >#
> >
> >count=0
> >while [ $count -lt 30 ]; do
> >     for i in `find $1 -maxdepth $count -type d |
\
> >           perl -we '{ while(<>) { chomp; print "\x27$_\x27\n" } }'`;
> >        do mv -i $i ` echo $i | tr '[A-Z]' '[a-z]' |
\
> >           perl -we '{ while(<>) { chomp; print "\x27$_\x27\n" } }'`;
> >     done;
> >     count=$[$count + 1];
> >done


--
To unsubscribe: mail majordomo at ale.org with "unsubscribe ale" in message body.





More information about the Ale mailing list