LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
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


Reply
  Search this Thread
Old 01-03-2008, 01:37 PM   #1
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
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.
 
Old 01-03-2008, 01:54 PM   #2
fuzzyworm
Member
 
Registered: Sep 2003
Location: Stroud, UK
Distribution: Kubuntu, Debian
Posts: 149

Rep: Reputation: 15
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
 
Old 01-03-2008, 01:58 PM   #3
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
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.
 
Old 01-03-2008, 02:06 PM   #4
dive
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467

Rep: Reputation: Disabled
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.
 
Old 01-03-2008, 02:14 PM   #5
fuzzyworm
Member
 
Registered: Sep 2003
Location: Stroud, UK
Distribution: Kubuntu, Debian
Posts: 149

Rep: Reputation: 15
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.
 
Old 01-03-2008, 02:16 PM   #6
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
ok now i understand the for i in * part. thank you for clearing that up.
 
Old 01-03-2008, 02:34 PM   #7
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
Quote:
Originally Posted by dive View Post
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?
 
Old 01-03-2008, 02:39 PM   #8
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
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
 
Old 01-03-2008, 03:26 PM   #9
dive
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467

Rep: Reputation: Disabled
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.
 
Old 01-03-2008, 03:29 PM   #10
dive
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467

Rep: Reputation: Disabled
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.
 
Old 01-03-2008, 04:42 PM   #11
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
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.
 
Old 01-03-2008, 05:10 PM   #12
dive
Senior Member
 
Registered: Aug 2003
Location: UK
Distribution: Slackware
Posts: 3,467

Rep: Reputation: Disabled
Quote:
Originally Posted by lleb View Post
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.
 
Old 01-03-2008, 06:08 PM   #13
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by lleb View Post
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.
Quote:
many thanks.
Thank this guy instead

Quote:
still ubber new to scripts and coding.
Then you should his advice first.
 
Old 01-03-2008, 06:31 PM   #14
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
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.
 
Old 01-03-2008, 11:10 PM   #15
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora/Pop!_OS
Posts: 2,980

Original Poster
Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
Quote:
Originally Posted by dive View Post
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.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Cannot replace spaces w/ underscores clem_c_rock Linux - Newbie 7 09-27-2007 01:17 PM
Need a script to search and replace text in file using shell script unixlearner Programming 14 06-21-2007 10:37 PM
need to replace spaces with comma (ascii file) ferradura Linux - Software 3 02-02-2007 08:39 PM
How do i change spaces inside a txt file, and replace space with backslash \? repolona Linux - Newbie 1 05-24-2006 05:08 AM
How to replace spaces in filenames with underscores rosslaird Linux - Software 4 02-22-2005 01:08 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

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

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration