bergman on 22 Feb 2006 16:09:16 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] bash script help needed (take 2)


Ooops...I sent the wrong version of my reply...see below for the full info...

In the message dated: Wed, 22 Feb 2006 09:39:56 EST,
The pithy ruminations from Art Alexion on 
<[PLUG] bash script help needed> were:

=> 
=> I am trying to iron out a script that renames all files in a current
=> directory to replace embedded spaces with underscores, and makes
=> everything lower case.

A common need...and a fun "quiz" type interview question.

=> 
=> The suggestion that I was given was (in pertinent part):
=> 
=> for OLD in *
=>   do
=>     NEW=`echo $OLD|sed s/\ /\_/g | tr [:upper:] [:lower:]`
=>     echo "OLD=\"$OLD\""
=>     echo "NEW=\"$NEW\""
=>     echo -e "mv \"$OLD\" \"$NEW\"\n"
=>   done
=> 
=> But while the messages sent to the console indicated what I wanted to do
=> was happening, and there were no errors reported, no changes were
=> actually being made to the filenames.
=> 
=> I read the echo man page and it seemed that the line
=> 
=> echo -e "mv \"$OLD\" \"$NEW\"\n"
=> 
=> didn't actually execute the mv command, so I added the line
=> 
=> mv $OLD $NEW

OK.


=> 
=> after it, so it now reads
=> 
=> for OLD in *
=>   do
=>     NEW=`echo $OLD|sed s/\ /\_/g | tr [:upper:] [:lower:]`
=>     echo "OLD=\"$OLD\""
=>     echo "NEW=\"$NEW\""
=>     echo -e "mv \"$OLD\" \"$NEW\"\n"
=>     mv $OLD $NEW
=>   done
=> 
=> But this results in the error
=> 
=> mv: when moving multiple files, last argument must be a directory

Good. You're actually lucky to get this message. I've seen instances where this 
kind of simple programming error has destroyed a production e-commerce database 
server...

What doe the echo statements display before the error message? Are they:

	OLD="*"
	NEW="*"
	mv "*" "*"

That's what I'd expect if there are no files or directories in the current directory.

If there are files in the current directory with spaces in their names, then
you'd see something like:
	OLD="file name with spaces"
	NEW="file_name_with_spaces"
	mv "file name with spaces" "file_name_with_spaces"
However, the mv command actually gets called as:

	mv  file name with spaces  file_name_with_spaces

(note the lack of quotes). Thus, mv receives the following arguments:

	file
	name
	with
	spaces
	file_name_with_spaces

and promptly checks if "file_name_with_spaces" is a directory. If not, you get
an error message.

Try changing the mv command to:
	mv "$OLD" "$NEW"

=> 
=> even though $NEW does not yet exist, so I am not really moving multiple
=> files.

The issue isn't that $NEW doesn't exist, but either that the initial
expansion of the "*" wildcard failed to produce a list of files to be
renamed, thus the literal character "*" is passed to the mv command,
or that the expansion succeeded, and spaces are being passed to the
mv command.

=> 
=> What am I doing wrong?

Well, what you're "doing wrong" is not checking or escaping whitespace
in the results of the metacharacter expansion before calling mv(1). The
action of mv will vary, depending on what files and directories are in
the directory where the script is executing.


I'd suggest that you go back and take another look at the thread "Interactive 
rm" from a couple of weeks ago. That thread deals with this very issue--how the 
shell handles wildcard expansion.

You may also want to look at:

	http://www.oreilly.com/catalog/bash3/
	http://www.oreilly.com/catalog/shellsrptg/
	
Mark


----
Mark Bergman
bergman@merctech.com
Seeking a Unix/Linux sysadmin position local to Philadelphia or via telecommuting

http://wwwkeys.pgp.net:11371/pks/lookup?op=get&search=bergman%40merctech.com


=> 
=> -- 
=> 
=> _______________________________________
=> Art Alexion
=> Arthur S. Alexion LLC
=> 
=> PGP fingerprint: 52A4 B10C AA73 096F A661  92D2 3B65 8EAC ACC5 BA7A
=> The attachment -- signature.asc -- is my electronic signature; no need for alarm.
=> Info @ http://mysite.verizon.net/art.alexion/encryption/signature.asc.what.html
=> 
=> Key for signed PDFs available at
=> http://mysite.verizon.net/art.alexion/encryption/ArthurSAlexion.p7c
=> The validation string is TTJY-ZILJ-BJJG.
=> ________________________________________
=> 
=> 
=> --------------enig14E73DE54C91A8F7AFB7398C
=> Content-Type: application/pgp-signature; name="signature.asc"
=> Content-Description: OpenPGP digital signature
=> Content-Disposition: attachment; filename="signature.asc"
=> 
=> -----BEGIN PGP SIGNATURE-----
=> Version: GnuPG v1.4.1 (GNU/Linux)
=> Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
=> 
=> iQCVAwUBQ/x3vELG/oYII0YuAQJUCwP/cp5qM6ZoT6VPmZlqFfa9T3K0brhBQ7/A
=> icwbq2Fuu+YV0Z54c1sbD9JfXYXGq/lQySHqs/Cfqg62dU+A5qR1me0Hu4HQyjgU
=> nkniyuJJpB/bmmHW1Do/MthYp3DIhYzTdrDCw8Xo/1e2temd9iUeNYqvQ19oCsBt
=> gHYrP/CWRKI=
=> =j4DK
=> -----END PGP SIGNATURE-----


___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug