Boston Linux & Unix (BLU) Home | Calendar | Mail Lists | List Archives | Desktop SIG | Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings
Linux Cafe | Meeting Notes | Blog | Linux Links | Bling | About BLU

BLU Discuss list archive


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

simple bash script question



matthew nicholson wrote:
> cat list2 | while read line; do line2=${line//\(/}; line3=${line2//\)/};
> fline=${line//\ /\\ };fline3=${fline//\(/\\\(};fline4=${fline3//\)/\\
> \)}; fline2=${line3//\ /\\ }; echo "mv $fline4 $fline2"; mv -v $fline4
> $fline2; done;

Reformatted, and statements reordered to make a bit more sense:

while read line;
do
         fline=${line//\ /\\ };
         fline3=${fline//\(/\\\(};
         fline4=${fline3//\)/\\\)};

         line2=${line//\(/};
         line3=${line2//\)/};
         fline2=${line3//\ /\\ };

         echo "mv $fline4 $fline2";
         mv -v $fline4 $fline2;
done;


> however, everytime i run this, mv, with every file, says:
> 
> mv: invalid option -- \
> Try `mv --help' for more information.

I kept getting:

mv: when moving multiple files, last argument must be a directory

suggesting that mv was seeing more than two arguments.

You're not doing a fair comparison with your echo command, because you 
have all of its arguments in quotes. Putting quotes around the arguments 
to mv leads to:

mv: cannot stat `file\\ with\\ \\(spaces\\ and\\ parens\\).txt': No such 
file or directory

which doesn't precisely point out the problem, but something is off in 
the quoting and escaping.

What's more important is that you're going to a lot of unnecessary work 
on the file names to escape things that could simply be handled by 
putting them in quotes.

It also simplifies matters if you put your code into a file instead of 
trying to run it directly on the command line, avoiding a layer of 
interpolation.

Here's a far simpler version that works:

while read line;
do
         src=$line;
         des=${line// /-};
         des=${des//(/-};
         des=${des//)/-};
         echo mv [$src] [$des];
         mv -v "$src" "$des";
done;


(If you tried entering this directly on the command line, you might have 
to put back some of the additional escaping you had on the substitutions.)


% echo file\ with\ \(spaces\ and\ parens\).txt | sh renm.sh
mv [file with (spaces and parens).txt] [file-with--spaces-and-parens-.txt]
`file with (spaces and parens).txt' -> `file-with--spaces-and-parens-.txt'


This version maps both spaces and parens to dash. Adjust as desired.


> better ways to do this?

Others have mentioned Perl. There's actually a stock 'rename' script 
written in Perl that has been around for a decade or more which accepts 
a regular expression on the command line and can easily strip out 
unwanted characters:

rename 'tr/[characters you don't want]/[what they map to]/' *.mp3

For example, this:

rename -v 'tr/ ()/-/' *.mp3

does the same thing as the script above.

  -Tom

-- 
Tom Metro
Venture Logic, Newton, MA, USA
"Enterprise solutions through open source."
Professional Profile: http://tmetro.venturelogic.com/




BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org