Solved

mv command not working as expected

Posted on 2012-03-12
5
1,393 Views
Last Modified: 2013-11-15
I have a need to replace spaces with underbars in all the directory tree from a certain sub-directory. The files were copied on an external drive from a family member that uses Windows.  I prefer to use *nix things, so for Windows I use Cygwin.  

Given that I have a testing file "My Family" in the current working directory, issuing the following command does the expected:

mv -T "My Family" My_Family

I want to use find to sweep all the files and directories from my starting directory, and pass each file/directory name to a script that does the same thing, but allows for the passing of arguments -- So the entire script (called sp2underbar) is:

#!/bin/bash
targ=`echo $1 | tr ' ' '_'`
/usr/bin/mv -T \'$1\' $targ              

The execution of the script gives this:

$ sp2underbar  "My Family"
/usr/bin/mv: extra operand `My_Family'
Try `/usr/bin/mv --help' for more information.

If I substitute for the variables as they would appear in the script and run the result manually on the command line, the rename works as expected.

I tried the same test exercise on an actual Linux box with the same results, so please don't advise that there is "something wrong with Cygwin"....

So what else is it? What am I missing?
0
Comment
Question by:Kimberly_B
5 Comments
 
LVL 84

Accepted Solution

by:
ozo earned 500 total points
Comment Utility
/usr/bin/mv -T "$1" $targ
0
 
LVL 31

Expert Comment

by:Frosty555
Comment Utility
Your escaped single quotes are not having the desired effect, and the "My Family" subdirectory is being treated as two distinct parameters by the mv command ("My", and "Family").

Try replacing the single quotes with doublequotes:

#!/bin/bash
targ=`echo $1 | tr ' ' '_'`
mv -T "$1" "$targ"

Open in new window


You can set up the script to allow extra arguments to pass to mv through some clever use of parameter shifting like so:

#!/bin/bash
src="$1"
targ=`echo $1 | tr ' ' '_'`
shift
echo $targ;
mv -T $@ "$src" "$targ"

Open in new window

0
 

Author Comment

by:Kimberly_B
Comment Utility
Changing single to double quotes had no effect on the outcome.  If the source is a file then the target is to be a file (not a directory) and if the source is a directory, then the target is to be a directory as well.  In this example "My Family" is a file.  I am using the -T flag.

I don't see what benefit `shift` has in this discussion, but maybe I'm just dense.  The only reason for the script was to simplify passing the source name in as the only argument, and using that to calculate the target name. Script would likely run from a `find` command... like this:

# Pass each file name to the script, script renames based on the argument passed in
find . -type f -exec sp2underbar "{}" \;    

# Same for directories, in a subsequent pass
find . -type d -exec sp2underbar "{}" \;
0
 

Author Closing Comment

by:Kimberly_B
Comment Utility
Yep, tried to get too fancy -- didn't need to escape the quotes in this case -- originally was trying to run this as a one-liner and do the substitute for space directly on the "find" command line (where escapes were needed), then brought that thinking into the script when I decided to go that route.   KISS principle applies.  Thanks!
0
 
LVL 14

Expert Comment

by:mikelfritz
Comment Utility
One more way:

find .  | while read targ;
do
target=`echo "$targ" | sed 's/ /_/g'`;
mv "$file" "$target";
done;


You would have to run this over and over until it traverses the structure since it changes from the root up and files in higher dirs wouldn't be found since the parent name changed.  Could be wrapped in a while loop I guess.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

I use more than 1 computer in my office for various reasons. Multiple keyboards and mice take up more than just extra space, they make working a little more complicated. Using one mouse and keyboard for all of my computers makes life easier. This co…
Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
The viewer will learn how to create multiple layers to apply various filters and how to delete areas from each layer’s filter.
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now