LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   bash - replace all spaces in file, folder names (http://www.linuxquestions.org/questions/programming-9/bash-replace-all-spaces-in-file-folder-names-635821/)

babag 04-16-2008 03:52 PM

bash - replace all spaces in file, folder names
 
how would i do this?

i have a folder i just tried ro copy and it wouldn't
do it. i'm suspecting it's because of spaces in the
file and folder names.

i need a simple command to recursively replace all
of the " " with "_" in this folder's files and
subfolders.

thanks,
BabaG

eco 04-16-2008 04:07 PM

Try using sed

$ echo "Hello World"|sed -e 's/\ /_/g'


This way, you might not even have to rename your folders... just do the following


The following fails:
mkdir "test me"
$ for i in `ls -d test\ me/`; do echo $i; done
test
me/

So try this:
$ for i in `ls -d test\ me/|sed -e 's/\ /_/g'`; do echo $i|sed -e 's/_/\ /g'; done
test me/


Hope this helps a bit
-Ed

ghostdog74 04-16-2008 09:04 PM

try , as far as possible , not to use ls in combination with for loop, unless really no choice.

eco 04-17-2008 12:01 AM

Hi ghostdog74,

I've always done it and never (that I know of) had any problems.

Could you let me know why it's bad practice? Keen to learn a new thing today. ;)

Thanks
-Ed

konsolebox 04-17-2008 02:05 AM

please tell us the command you used to copy.

and i'm also kind of confused. you said you're doing ro copy.. can the source files be modified or are you trying to copy the file with namespaces replaced with _ in the target?..

about ls.. probably it is not good because it sometimes print the files with colors.
but perhaps using the proper options can prevent the unexpected errors.

ghostdog74 04-17-2008 02:07 AM

Quote:

Originally Posted by eco (Post 3123735)
Hi ghostdog74,

I've always done it and never (that I know of) had any problems.

Could you let me know why it's bad practice? Keen to learn a new thing today. ;)

Thanks
-Ed

Code:

# ls -ltr
total 0
-rw-r--r-- 1 root root 0 Apr 17 12:08 file with spaces
# for files in `ls`
> do
> echo $files
> done
file
with
spaces
# for files in `ls`; do mv "$files" "otherfile"; done
mv: cannot stat `file': No such file or directory
mv: cannot stat `with': No such file or directory
mv: cannot stat `spaces': No such file or directory

# for files in *; do mv "$files" "otherfile"; done
# ls -ltr
total 0
-rw-r--r-- 1 root root 0 Apr 17 12:09 otherfile


konsolebox 04-17-2008 02:49 AM

you can do IFS=$'\n' before to prevent separation within spaces. also add -1 to the parameter of ls.

colucix 04-17-2008 03:06 AM

What about to let the wildcard do the job? If you have a directory called "my directory with spaces" you can do simply
Code:

cp -pR my* /path/to/destination/dir
if you don't have other files or directories beginning with "my".

konsolebox 04-17-2008 03:10 AM

of course.. i think it's better to to use wildcards when it's possible most of the time. you can also use it within directories like:

cp -pR dir/* /path/dest

to know how things work, do

echo cp -pR dir/* /path/dest

ta0kira 04-17-2008 05:44 AM

Code:

find -depth -name "* *" | while read file; do
  rename "$( basename "$file" )" "$( basename "$file" | sed "s/ /_/g" )" "$file"
done

This will replace all spaces in all file names recursively, so be careful what directory you call it from!
ta0kira

ghostdog74 04-17-2008 06:26 AM

Quote:

Originally Posted by konsolebox (Post 3123848)
you can do IFS=$'\n' before to prevent separation within spaces. also add -1 to the parameter of ls.

you mean like this?
Code:

# IFS=$'\n'
# for files in `ls -1`;do echo "$i";done

have you tried? I am curious about your results

ghostdog74 04-17-2008 06:28 AM

Quote:

Originally Posted by ta0kira (Post 3123984)
Code:

find -depth -name "* *" | while read file; do
  rename "$( basename "$file" )" "$( basename "$file" | sed "s/ /_/g" )" "$file"
done

This will replace all spaces in all file names recursively, so be careful what directory you call it from!
ta0kira

is rename a perl script? does it have the ability to do the sed portion, so that sed can be removed. all done using rename.

eco 04-17-2008 08:04 AM

Quote:

Originally Posted by konsolebox (Post 3123848)
you can do IFS=$'\n' before to prevent separation within spaces. also add -1 to the parameter of ls.

Works great... very smooth and so much better than my sed! ;)

ararus 04-17-2008 09:18 AM

Quote:

Originally Posted by ta0kira (Post 3123984)
Code:

find -depth -name "* *" | while read file; do
  rename "$( basename "$file" )" "$( basename "$file" | sed "s/ /_/g" )" "$file"
done

This will replace all spaces in all file names recursively, so be careful what directory you call it from!
ta0kira

This is completely redundant, rename translates patterns itself.

Code:

find -type d -exec rename ' ' '_' {} \;
find -type f | xargs rename ' ' '_'

You rename directories first for obvious reasons (you can't rename multiple directory components at the same time, which is also why we use -exec). Then rename the files, using xargs to pass mulitple files at once. Rename does the space to _ translation, no need for sed.

Quote:

is rename a perl script?
Nope.

Code:

# file $(which rename)
/usr/bin/rename: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped

edit:
actually, you might want to nul terminated the filenames:

Code:

find ... -print0 | xargs -0 ...

colucix 04-17-2008 09:26 AM

Quote:

Quote:

is rename a perl script?
Nope.
Actually it is a perl script on Debian-based systems, an ELF executable on the others.


All times are GMT -5. The time now is 01:44 PM.