[ale] scripting (looping through filenames containing spaces)

Gary Maltzen maltzen at MM.COM
Tue Jul 4 18:11:07 EDT 2000


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