Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place! |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
 |
|
01-03-2008, 01:37 PM
|
#1
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
|
script to replace spaces with -
I have seen it before but am having major failure on finding it here at LQ.
I would like a simple script that i can run in a directory that will remove all of the ' ' in a name of a file and replace them with '-' or '_' either will be fine.
also can this be run to affect sub-directories and directory names them self?
many thanks.
still ubber new to scripts and coding.
|
|
|
01-03-2008, 01:54 PM
|
#2
|
Member
Registered: Sep 2003
Location: Stroud, UK
Distribution: Kubuntu, Debian
Posts: 149
Rep:
|
Code:
for i in *; do mv "$i" ${i// /_}; done;
should do the trick. Note that it will do this with all files and subfolders in the current directory.
Hope this helps
|
|
|
01-03-2008, 01:58 PM
|
#3
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
Original Poster
|
now for my education. as i know next to nothing about code.
i could make a bash script:
#!/bash/bin
for i in *; do mv "$i" ${i// /_};
done
what is the last ; for?
and what is the 'for i in' part of the code telling the system to do.
i get the do mv ... part as the string ($)i is everything? and the part inside of the { } is if it is // then change it to /_ or if it is a space replace the space with an _, but still not sure what the code is tell me. i see it will work, just no clue why. trying to learn.
|
|
|
01-03-2008, 02:06 PM
|
#4
|
Senior Member
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467
Rep: 
|
My win2lin script. It can be invoked with a file/dir name ( win2lin some\ dir ) or just on its own in which case it will change all the files/dirs in current dir. It is recursive.
Code:
#!/bin/bash
function basic {
for i in *
do
if [ -d "$i" ]
then
cd "$i"
win2lin #name of this script. Must be in PATH or full path to script must be given.
cd ..
fi
tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed 's/\ -\ /-/g' | sed 's/__/_/g' \
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
[[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
done
}
function cmd {
for i in "$@"
do
tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed 's/\ -\ /-/g' | sed 's/__/_/g' \
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
[[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
[[ ! -d "$tempa" ]] && break
cd "$tempa"
win2lin #name of this script. Must be in PATH or full path to script must be given.
cd ..
done
}
[[ "$@" != "" ]] && cmd "$@"
[[ "$@" == "" ]] && basic
Last edited by dive; 01-03-2008 at 02:17 PM.
|
|
|
01-03-2008, 02:14 PM
|
#5
|
Member
Registered: Sep 2003
Location: Stroud, UK
Distribution: Kubuntu, Debian
Posts: 149
Rep:
|
That script ought to cover it better than my one line command.
However, in answer to your question:
a) I like to finish my lines with ';', but it should work without the final one.
b) (See man page for further info: http://www.ss64.com/bash/for.html )
Code:
for i in *; do ...; done;
Takes * (all files in current folder [or *.*, in some cases])
With each one in turn, sets it to 'i', then executes the code
Hope this has helped.
Last edited by fuzzyworm; 01-03-2008 at 02:15 PM.
|
|
|
01-03-2008, 02:16 PM
|
#6
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
Original Poster
|
ok now i understand the for i in * part. thank you for clearing that up.
|
|
|
01-03-2008, 02:34 PM
|
#7
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
Original Poster
|
Quote:
Originally Posted by dive
My win2lin script. It can be invoked with a file/dir name ( win2lin some\ dir ) or just on its own in which case it will change all the files/dirs in current dir. It is recursive.
Code:
#!/bin/bash
function basic {
for i in *
do
if [ -d "$i" ]
then
cd "$i"
win2lin #name of this script. Must be in PATH or full path to script must be given.
cd ..
fi
tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed 's/\ -\ /-/g' | sed 's/__/_/g' \
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
[[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
done
}
function cmd {
for i in "$@"
do
tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed 's/\ -\ /-/g' | sed 's/__/_/g' \
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
[[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
[[ ! -d "$tempa" ]] && break
cd "$tempa"
win2lin #name of this script. Must be in PATH or full path to script must be given.
cd ..
done
}
[[ "$@" != "" ]] && cmd "$@"
[[ "$@" == "" ]] && basic
|
now that is a might set of code for my little head to wrap around. mind educating me a bit. what is sed?
i can see that sed is looking at a situation of the ls output and if it finds something it is going to replace it with the other... so sed 's/ /_/g' if i understand is telling me that string 's' of / to replace with _ and the /g is go? kind of like in vi editing?
what is the rest of it tell me to do?
|
|
|
01-03-2008, 02:39 PM
|
#8
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
Original Poster
|
Code:
sh remove_space2.sh
remove_space2.sh: line 32: unexpected EOF while looking for matching `"'
remove_space2.sh: line 33: syntax error: unexpected end of file
now when i look at the code i typed in with vi :set number i only show 32 lines of code...
Code:
1 #!/bin/bash
2 #
3 # remove spaces in names of files and replace them with '_'
4 #
5 function basic {
6 for i in *
7 do
8 if [ -d "$i$ ]
9 then
10 cd "$i"
11 win2lin #name of this script from LQ member dive. Must be in PATH or full path t o script must be given.
12 cd ..
13 fi
14 tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed -e 's/\ -\ /-/g' | sed 's/__/_/ g' \ | sed "s#'##g" | sed "s#;##g' | sed "s#,##g")
15 [[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
16 done
17 }
18
19 function cmd {
20 for i in "$@"
21 do
22 tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed -e 's/\ -\ /-/g' | sed 's/__/_/ g' \ | sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
23 [[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
24 [[ ! -d "$tempa" ]] && break
25 cd "$tempa"
26 win2lin #name of this script from LQ member dive. Must be in PATH or full path to script must be given.
27 cd ..
28 done
29 }
30
31 [[ "$@" != "" ]] && cmd "$@"
32 [[ "$@" == "" ]] && basic
:set number
so were did i screw up
|
|
|
01-03-2008, 03:26 PM
|
#9
|
Senior Member
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467
Rep: 
|
I can see line 8 is wrong and causes that error. Also 11 and 26 need to point to this script. If you rename it to remove_space2.sh then replace win2lin with that and either put it in your path or provide full path to the script.
14 and 22 are also wrong. You have made 2 lines into 1. The \ at the end of each line tells bash that the command continues on the next line.
Last edited by dive; 01-03-2008 at 03:32 PM.
|
|
|
01-03-2008, 03:29 PM
|
#10
|
Senior Member
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467
Rep: 
|
sed = stream editor. In
sed 's/ /_/g'
The s means substitute. The g means global. So the command tells sed to substitute all spaces ( / / ) with underscore ( /_/ ) globally.
There are other sed commands in there to make __ into _ and also remove ; and ,
Last edited by dive; 01-03-2008 at 03:34 PM.
|
|
|
01-03-2008, 04:42 PM
|
#11
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
Original Poster
|
ok made these changes...
1. adjusted line 8, 13, 22 (they are now 8, 14, and 23) to fix typo and add a break (hit the return key)
2. changed name from win2lin to remove_space2.sh as that is what i created it as, that should work i hope.
3. still getting errors... what exactly do you mean put it in my path?
can i just be in the directory of the script and do : sh remove_space2.sh and have it run on that directory?
Code:
sh remove_space2.sh
remove_space2.sh: line 34: unexpected EOF while looking for matching `"'
remove_space2.sh: line 35: syntax error: unexpected end of file
ray@sabAMD64 ~/torrents $ cat remove_space2.sh
#!/bin/bash
#
# remove spaces in names of files and replace them with '_'
#
function basic {
for i in *
do
if [ -d "$i" ]
then
cd "$i"
remove_space2.sh #name of this script from LQ member dive. Must be in PATH or full path to script must be given.
cd ..
fi
tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed -e 's/\ -\ /-/g' | sed 's/__/_/g' \
| sed "s#'##g" | sed "s#;##g' | sed "s#,##g")
[[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
done
}
function cmd {
for i in "$@"
do
tempa=$(echo "$i" | sed 's/ /_/g' | sed 's/_-_/-/g' | sed -e 's/\ -\ /-/g' | sed 's/__/_/g' \
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
[[ "$i" != "$tempa" ]] && mv -v "$i" "$tempa"
[[ ! -d "$tempa" ]] && break
cd "$tempa"
remove_space2.sh #name of this script from LQ member dive. Must be in PATH or full path to script must be given.
cd ..
done
}
[[ "$@" != "" ]] && cmd "$@"
[[ "$@" == "" ]] && basic
so i hope i made the fixes you caught correctly.
also thank you very much for explaining what sed is and the s and g. to me this is one of the FOSS communities greatest strengths. the willingness of people to take time to educate others.
|
|
|
01-03-2008, 05:10 PM
|
#12
|
Senior Member
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467
Rep: 
|
Quote:
Originally Posted by lleb
Code:
| sed "s#'##g" | sed "s#;##g' | sed "s#,##g")
|
There's an error here: the 2nd sed command starts with a " and ends with a '.
Should be:
Code:
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
Are you typing all this manually? Easier to copy and paste.
For the lines that call the script again you will probably need to put /path/to/remove.space2.sh
But unless this is the only script that you ever want to use it would be eaiser in the long run to add a scripts folder in your home directory and then add it to your PATH env variable in .bashrc or .bash_profile:
export PATH=$PATH:~/scripts
This way you will only ever need to call the name of the script.
Last edited by dive; 01-03-2008 at 05:56 PM.
|
|
|
01-03-2008, 06:08 PM
|
#13
|
Senior Member
Registered: Aug 2006
Posts: 2,697
|
Quote:
Originally Posted by lleb
I have seen it before but am having major failure on finding it here at LQ.
I would like a simple script that i can run in a directory that will remove all of the ' ' in a name of a file and replace them with '-' or '_' either will be fine.
|
Code:
for files in *
do
if [ -f "$files" ];then
case $files in
*" "* )
newfile=`echo $files | sed 's/ /./g'`
mv "$files" "$newfile"
;;
esac
fi
done
Quote:
also can this be run to affect sub-directories and directory names them self?
|
yes. I leave it to you to try it out yourself.
Thank this guy instead
Quote:
still ubber new to scripts and coding.
|
Then you should his advice first.
|
|
|
01-03-2008, 06:31 PM
|
#14
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
|
It's a little late here, but I always use the perl rename (aka prename) command, a script provided as part of the perl package. It uses the basic sed replacement syntax.
rename -v "y/\ /_/" ./*
To run it on subdirectories simply use the find command:
find . -exec rename -v "y/\ /_/" '{}' \;
I've been using it all weekend to clean up the file names on my music directory. I've even created an alias from it specifically for quickly removing spaces from filenames.
|
|
|
01-03-2008, 11:10 PM
|
#15
|
Senior Member
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,992
Original Poster
|
Quote:
Originally Posted by dive
There's an error here: the 2nd sed command starts with a " and ends with a '.
Should be:
Code:
| sed "s#'##g" | sed "s#;##g" | sed "s#,##g")
Are you typing all this manually? Easier to copy and paste.
|
Yes, when i tried to copy/paste i ended up with lines that were way out of wack so i just did it manually... thus all the typo's
Quote:
For the lines that call the script again you will probably need to put /path/to/remove.space2.sh
But unless this is the only script that you ever want to use it would be eaiser in the long run to add a scripts folder in your home directory and then add it to your PATH env variable in .bashrc or .bash_profile:
export PATH=$PATH:~/scripts
This way you will only ever need to call the name of the script.
|
ok still not 100% on how to add things to my .bashrc as in my home directory the only .bashXXX i have is my bash history. gentoo/sabayon does some strange things when it comes to that. i had a devil of a time getting an alias to be part of the bash environment.
once i replaced the ' with " it worked like a charm. thank you.
|
|
|
All times are GMT -5. The time now is 12:42 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|