LinuxQuestions.org
Review your favorite Linux distribution.
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-2016, 10:47 AM   #1
iFunction
Member
 
Registered: Nov 2015
Posts: 248

Rep: Reputation: Disabled
replace spaces with underscores for partition label


Hi there,

struggling a little bit here, I want to make it easy for someone to enter a name for a partition in a script I have written, but can't get it to work. this is what I have so far, but any attempt to strip out the spaces makes the script just end without finishing the script:
Code:
echo "Enter event name >"
read event
sudo mkdosfs -n $event /dev/sda1 -s 128 -F 32 -I
this works so long as you put in a name with no spaces and all capital letters but I want so make it so it is idiot proof. I was under the impression that you could do it all in one line, but am starting to think you have to condition the variable first.

Please help
 
Old 01-03-2016, 11:41 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,974

Rep: Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179Reputation: 3179
What have you tried in way of stripping the spaces?
You also quote your variables as a good habit.

I would add, that if you are going to make it truly idiot proof (very difficult tasks because idiots can excel some times ), you may wish to consider what if they enter characters other than spaces which would not be allowed, such as an asterisk
 
Old 01-03-2016, 12:38 PM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 24,119

Rep: Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336
To allow spaces you need to clear IFS.
IFS=
You should save the old value and restore it at the end of the script. I agree the you should check for valid characters as well as length which is no more than 11.

Last edited by michaelk; 01-03-2016 at 05:32 PM.
 
Old 01-03-2016, 01:17 PM   #4
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,113

Rep: Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159
Quote:
Originally Posted by iFunction View Post
Hi there,

struggling ....
Please help
if it is gotten off the command line then it will be seen as arg1 and arg2 etc if not in quotes.

Code:
echo "Enter event name >"
read event


# CAPs all letters

event=${event^^}


#ensures only one space between each word

event="$(echo -e "${event}" | fmt -u )"

#removes leading white space on both ends of string

event="$(echo -e "${event}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"

# checks for spaces then adds an underscore between each space

event=${event// /_}


sudo mkdosfs -n $event /dev/sda1 -s 128 -F 32 -I
and here is this peice of code I wrote for taking in command line, it is set up to take in just $1 you can modify it to check for what ever condistion you need to have the user pass before it runs the rest of the script.



Code:
#####################
## DO NOT CHANGE ####
runTime=1 ###########        
convertN=$1 #########
#####################
# gets amount of files wanted to resample on run
# from command line args
function rst(){

if [[ convertN -lt runTime ]]; then
	echo " you forgot to enter an amount to resample"
	ConvertNum=0
	exit 1
	else
	ConvertNum=$((convertN))
return $ConvertNum #pass the var to space land

fi

}
something like this perhaps

read how to take in more then one argument off command line in link

Code:
#!/bin/bash
       
VolName=$1  
Nbytes=$2
Nfats=$3

function MakeDiskyThingy(){
  
if [[ ! -z $Nbytes && $Nbytes =~ ^[-+]?[0-9]+$ ]] ; then
	if [[ ! -z $Nfats && $Nfats =~ ^[-+]?[0-9]+$ ]] ; then
	
	sudo mkdosfs -n "$VolName" /dev/sda1 -s "$Nbytes" -F "$Nfats" -I
	
	else
	 echo " you made an error please try again"
         exit 1
		 
fi

}


# code goes here to check your string name and modify it if needed or
# do what ever you want to it, then use your function call to complete
# the task

echo "Enter volume-name, sectors-per-cluster, and FAT-size >"
read VolName


# CAPs all letters

VolName=${VolName^^}


#ensures only one space between each word

VolName="$(echo -e "${VolName}" | fmt -u )"

#removes leading white space on both ends of string

VolName="$(echo -e "${VolName}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"

# checks for spaces then adds an underscore between each space

VolName=${VolName// /_}


MakeDiskyThingy
if you want to strip white space and make in one long string then use this
Code:
event=${event// /}
you might want to also change your where is the vol at into a $var, and call it $4 maybe figure that part out too.

Code:
/dev/sdb1 

#would acually be turned into a var name for user input 

sudo mkdosfs -n "$VolName" /dev/sda1 -s "$Nbytes" -F "$Nfats" -I

# would then look like this

sudo mkdosfs -n "$VolName" "$DeviceName" -s "$Nbytes" -F "$Nfats" -I
that way it is not hard coded just incase theirs is not /dev/sda1

read up on taking in more then one argument off command line

Command-line-Arguments

let me know if you're cooking with oil or not

Last edited by BW-userx; 01-03-2016 at 02:40 PM.
 
Old 01-03-2016, 03:27 PM   #5
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,113

Rep: Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159
Quote:
Originally Posted by iFunction View Post
Hi there,

struggling


Please help

Quote:
Originally Posted by BW-userx View Post
let me know if you're cooking with oil or not
or you could read this instead and let me know if it works for you...

something like this even, this is the argument I gave the script

Code:
[userx@Voided testing]$ ./FormatUSB FristTry /dev/sdd1 128 32
then Taking your code and using it in this script I just wrote to give it a try...

there are some inconsistencies within this script _ I'll leave you with that to figure out, why?

what could they be used for but are they really necessary?

Code:
#!/bin/bash

VolName=$1  
DeviceName=$2
Nbytes=$3
Nfats=$4

VolName=${VolName^^}

# -z checks for NULL
#sets to default size or smallest 
 if [[ -z "$Nbytes" ]] ; then
	Nbytes="512"
 fi
 
 if [[ -z "$Nfats" ]] ; then
	Nfats="2"
 fi
 
#####################

if [[ $# -eq "4" ]] ; then
 	  
  if [[ ! -z $Nbytes && $Nbytes =~ ^[-+]?[0-9]+$ ]] ; then
	if [[ ! -z $Nfats && $Nfats =~ ^[-+]?[0-9]+$ ]] ; then
	
		umount "$DeviceName"
		
		sudo mkdosfs -n "$VolName" "$DeviceName" -s "$Nbytes" -F "$Nfats" -I
		 
else

     echo "you made a mistake try again"
     exit 1

fi
 fi
  fi
sorry I just had to give it a try myself even.

now put it in a loop and shift $1 $2 $3 $4

and see if you can get it to work.

Last edited by BW-userx; 01-03-2016 at 03:53 PM.
 
Old 01-03-2016, 04:56 PM   #6
iFunction
Member
 
Registered: Nov 2015
Posts: 248

Original Poster
Rep: Reputation: Disabled
Wow, loads of replies here, basically I have written a script that will format a 64Gb usb stick to FAT32. They are only going to put in one name as it is so clients can see their data taken from a VBOX set up for racing. I originally had the name in there, but it occurred to me that just to change the name for each event would be fine if it was only on a couple of raspberry pi's, but it is for 40 of them, so I gave the engineers enough credit to be able to write the name of the race track, but not enough credit to know not to use spaces and lower case letters. These USB sticks are gifted to the customers at the end of the events, and due to the company I work for, this is not the sort of simple mistake our engineers would make, so elements of these are for my learning. The slicker I can get it the better.

My other option is to do something similar to case, so they only had to pick a number from 1 to 8, though I would rather let them do the work. It's just that I am a complete beginner at bash but looking at some scripts, it did look like I could do this in only a couple of lines of code.

This is what I tried:
Code:
echo "Enter event name >"
read event
sudo mkdosfs -n ${event// /_} /dev/sda1 -s 128 -F 32 -I
and all it does is end the script. I also tried:
Code:
event=${event// /_}
This just ends the script also but as you can see, I am new to bash and the syntax seems properly alien to me.

hmm, I am doing something wrong, and yes at the moment they are inputting the name into the command line.
 
Old 01-03-2016, 05:04 PM   #7
iFunction
Member
 
Registered: Nov 2015
Posts: 248

Original Poster
Rep: Reputation: Disabled
What I really don't understand is that I just tried this:

Code:
echo "Enter event name >"
read event
event=${event// /_}
echo $event
sleep 5
to see if I could see what the variable "event" is holding, and again it is shutting the terminal window down before it gets to the sleep bit.
 
Old 01-03-2016, 05:12 PM   #8
iFunction
Member
 
Registered: Nov 2015
Posts: 248

Original Poster
Rep: Reputation: Disabled
Here is the complete script that works and will provide the desired results providing the name is typed in caps and underscores:
Code:
  GNU nano 2.2.6                                                                  File: formatusb.sh                                                                                                                                          

#/bin/bash

sudo umount /dev/sda1
# If the usb stick is mounted during fdisk, it needs rebooting
# before any other commands can run, so unmounting the usb helps
# the script run better.

(echo d; echo o; echo n; echo p; echo 1; echo ; echo ; echo t; echo b; echo w) |sudo fdisk /dev/sda
# this command passes the required user input:
# d - deletes partition. 
# o - creates a new DOS partition table.
# n - creates a new partition formatted to 'linux' and requires the following inputs
# p - choose primary partition - default.
# 1 - choose first partition - default.
#   - default start sector of partition.
#   - default end sector of partition - we are using entire usb.
# t - changes partition format.
# b - code for W95 DOS format - 'l' lists all the formats
# w - saves and exits - 'q' exits without excecuting the formatting' you have been warned.

clear
echo
echo
echo
echo "Enter event name >  "
read event 

echo $event
sleep 5
sudo mkdosfs -n $event /dev/sda1 -s 128 -F 32 -I
# This line formats the partition to FAT32 and names it.

zenity --info --text "Formatting complete.\n\nPlease remove usb"
# zenity is a library for displaying pop up messages for info or input.

clear
# there are a number of bugs with the raspberry pi that do not get
# addressed as the raspberry pi is by and large a development tool
# so doesn't need to be slick. The 'clear' command here just clears
# an error message that is one of these bugs.

sudo umount /dev/sda1
# again, to make sure the usb stick is unmounted before it is removed.
So why is adding that extra line stopping the script and shutting down the terminal window so fast??
 
Old 01-03-2016, 05:15 PM   #9
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,113

Rep: Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159
Quote:
Originally Posted by iFunction View Post
Wow, loads of replies here, basically I have written a script that will format a 64Gb usb stick to FAT32. They are only going to put in one name as it is so clients can see their data taken from a VBOX set up for racing. I originally had the name in there, but it occurred to me that just to change the name for each event would be fine if it was only on a couple of raspberry pi's, but it is for 40 of them, so I gave the engineers enough credit to be able to write the name of the race track, but not enough credit to know not to use spaces and lower case letters. These USB sticks are gifted to the customers at the end of the events, and due to the company I work for, this is not the sort of simple mistake our engineers would make, so elements of these are for my learning. The slicker I can get it the better.

My other option is to do something similar to case, so they only had to pick a number from 1 to 8, though I would rather let them do the work. It's just that I am a complete beginner at bash but looking at some scripts, it did look like I could do this in only a couple of lines of code.

This is what I tried:
Code:
echo "Enter event name >"
read event
sudo mkdosfs -n ${event// /_} /dev/sda1 -s 128 -F 32 -I
and all it does is end the script. I also tried:
Code:
event=${event// /_}
This just ends the script also but as you can see, I am new to bash and the syntax seems properly alien to me.

hmm, I am doing something wrong, and yes at the moment they are inputting the name into the command line.
show me what you are writing into the command line itself I'm not fully understanding that part.

Code:
ensure that all letters will be caps 

event=${event^^}
you could just try this too
Code:
echo "Enter event name >"
read event

event=${event// /}
event=${event^^} # lable has to be in caps
umount /dev/sda1

sudo mkdosfs -n "$event" /dev/sda1 -s 128 -F 32 -I

Code:
echo "enter a number 1...10 - wirte a list of names with the corrisponding numer to it \"
      then have them slecet a number"

case "$1" in
        "1")
            # format code here           
             ;;
         
        "2" )
            # format code here
            ;;
         
        "3" )
            # format code here
            ;;
        "4" )
            # format code here 
            
            ;;
         
        *)
            #default sction here if needed
esac
just follow the syntax for more options if needed. Remember if they put in a string that has spaces it in it will not work because it is now reading more then one argument.

Code:
[userx@Voided testing]$ mkdosfs -n Hey you /dev/sdd1 -s 128 -F 32 -I
mkfs.fat 3.0.28 (2015-05-16)
mkfs.fat: warning - lowercase labels might not work properly with DOS or Windows
you: No such file or directory
as you can see it did not like the first one, "Hey" giving a warning then the second one "you" errored it out so that it would not work at all. it was trying to use the "you" for the /dev/sdd1 argument. that is why it didn't work.


always when in doubt use the command line to see whats going on, if it works on in term then it will work in BASH script.

if they type in something like this into the term off your script

Code:
goo goo Bug Killers

this is what the term/BASH will read it as
$1 = goo
$2 = goo
$3 = Bug
$4 = Killers
it will never go into what it is I think you're trying to do, or have them do. you should put an instruction in your read out to term before taking in the information first to ensure that it is ONLY one word, and what format it needs to be in else make it error out, then have them figgure it out. it does not hurt to make people use their own brains sometimes. Their gammers right? They can't be that stupid.

your
Code:
 read event
is $1 and always will be $1 forever the way you have your script written.

try this and see what you can do with it

Code:
#!/bin/bash

echo "type in some stuff"

read -r
line=$REPLY
 
echo
echo "$line"
echo

Last edited by BW-userx; 01-03-2016 at 05:50 PM.
 
1 members found this post helpful.
Old 01-03-2016, 05:54 PM   #10
iFunction
Member
 
Registered: Nov 2015
Posts: 248

Original Poster
Rep: Reputation: Disabled
Thank you BW, this is very helpful, I will look at it tomorrow and see. The case statement to me looks to be the one, that way they don't have a choice as to what to enter.

Kind regards

iFunk
 
Old 01-03-2016, 05:59 PM   #11
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,113

Rep: Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159
Quote:
Originally Posted by iFunction View Post
Thank you BW, this is very helpful, I will look at it tomorrow and see. The case statement to me looks to be the one, that way they don't have a choice as to what to enter.

Kind regards

iFunk
The pleasure is all mine, let me know how it turns out.
 
Old 01-03-2016, 06:39 PM   #12
michaelk
Moderator
 
Registered: Aug 2002
Posts: 24,119

Rep: Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336
As stated you can use read to enter a string with spaces.
Code:
OLDIFS=$IFS
IFS=
echo "Enter event name >"
  read label
echo The label is $label
if [[ "$label" =~ [^0-9A-Za-z\ ]+ ]]; then
  echo "contains invalid characters"
fi
IFS=$OLDIFS

Results:
./program
Enter event name >
hey you
The label is hey you

To use a label with spaces you need to use quotes i.e.
Code:
mkdosfs -n "Hey you" /dev/sdd1 -s 128 -F 32 -I
A simpler approach instead of zenity would be a pause.
Code:
read -p "Formatting complete please remove drive, Press [enter] key to continue"
 
Old 01-03-2016, 06:48 PM   #13
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,113

Rep: Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159Reputation: 2159
Quote:
Originally Posted by michaelk View Post
To use a label with spaces you need to use quotes i.e.
Code:
mkdosfs -n "Hey you" /dev/sdd1 -s 128 -F 32 -I
that is what I was saying and showing him what happens when no quotes are used,

Code:
echo "type in some stuff"

read -r
line=$REPLY
 
echo
echo "$line"
reads everything written on command line, no need to unset IFS=

Last edited by BW-userx; 01-03-2016 at 06:49 PM.
 
Old 01-03-2016, 07:03 PM   #14
michaelk
Moderator
 
Registered: Aug 2002
Posts: 24,119

Rep: Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336Reputation: 5336
True...
 
Old 01-04-2016, 06:43 AM   #15
iFunction
Member
 
Registered: Nov 2015
Posts: 248

Original Poster
Rep: Reputation: Disabled
Ok, I have isolated the problem,
Code:
Code:

echo "type in some stuff"

read -r
line=$REPLY
 
echo
echo "$line"
Worked like a charm, that's all good, thanks for that. however, it doesn't like any commands with curly braces in, so I this just stops the script, no warning, no error message nothing, so everything works fine until something like this is put in the script:
Code:
event=${event// /_}
Any ideas why this would be?
 
  


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
replace 8 times successive spaces by | sumeet inani Linux - Newbie 12 10-06-2011 06:31 PM
Is there a script for changes spaces to underscores? DJOtaku Linux - General 4 02-04-2008 09:28 PM
script to replace spaces with - lleb Linux - Newbie 16 01-04-2008 04:15 PM
Cannot replace spaces w/ underscores clem_c_rock Linux - Newbie 7 09-27-2007 01:17 PM
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 10:09 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