tags:

views:

65

answers:

2

Suppose I have a directory containing the files

foo bar.txt  
foo baz.txt

(each with a space between 'o' and 'b'). Suppose I would like to do this:

for f in *.txt; do mv ${f} `basename ${f} .txt`; done

This fails because bash expands *.txt to

foo bar.txt foo baz.txt

instead of

foo\ bar.txt foo\ baz.txt

i.e. properly escaped as if I had used tab completion.

How can I get bash to properly escape its output?

+3  A: 

you put quotes in your variables. this way you preserve the space. Also, there's no need to use external command basename. the shell can do that for you. (assuming you are using bash)

for file in *.txt
do
 mv "$file" "${file%.txt}"
done
ghostdog74
..added the missing terminating quote
roe
thks. as you are adding it, i am also doing it.
ghostdog74
+1  A: 

Or if it is one off operation you can use vim:

> ls -al
foo bar.txt
foo baz.txt

Open vim and execute:

:r!ls *.txt

This loads files, then execute:

:%s/\(\(.*\)\.txt\)/mv "\1" "\2"/gc

This will replace the lines with:

mv "foo bar.txt" "foo bar"
mv "foo baz.txt" "foo baz"

Highlight all with Ctrl-v down, then enter : and type the rest of this command:

:'<,'>!bash

That will execute the highlighted commands in bash. Quit vim and check your directory:

> ls
foo bar
foo baz
stefanB
**Or** in `vim` just type: `:!for f in *.txt; do mv "${f}" "${f%.txt}"; done` (assuming Bash is your shell).
Dennis Williamson