Results 1 to 9 of 9
Hi linux user,
I try to make an easy string substitution inside a bash script.
I need to substitute the substring "=>" and all the space round this with
one ...
- 07-06-2007 #1Just Joined!
- Join Date
- Jul 2007
- Posts
- 4
bash string substitution problem
Hi linux user,
I try to make an easy string substitution inside a bash script.
I need to substitute the substring "=>" and all the space round this with
one symbol ... example:
original string: "xyz => uvw"
substitution : "xyz,uvw"
I have substituted " => " with this symbol ","
If I try to do this using a regular expression in a bash script:
------------test.sh------------
#!/bin/bash
st="xyz => uvw"
echo ${st/[ ]*=>[ ]*/,}
------------------------------
I obtain in output this:
xyz,
How can I obtain che correct result? :
xyz,uvw
can you help me?
p.s. I don't want to use external tool like sed or perl for performance reason.
- 07-06-2007 #2Linux User
- Join Date
- Aug 2006
- Posts
- 458
Code:echo ${st/ => /,}
- 07-06-2007 #3Linux User
- Join Date
- Jun 2007
- Posts
- 318
The form you're using (/) replaces only the 1st occurance. Use the 2nd form (//) which replaces all occurances. Plus, to handle TABs as well as spaces this is the command:
echo "${st//[[:space:]]*=>[[:space:]]*/,}"
- 07-10-2007 #4Just Joined!
- Join Date
- Jul 2007
- Posts
- 4
Hi vsemaska,
thank you for your reply, but if you apply your example with my example you obtain this:
xyz,
your script miss the second part of the string "uvw"
have you test your script?
I use a bash with this version "version 3.1.17(1)-release".
- 07-10-2007 #5
The problem is that the ${s/foo/bar} syntax actually uses shell patterns, I believe, and not regular expressions.
If we look at /[[:space:]]*=>[[:space:]]*/ as a shell pattern, it says "A space character, followed by any number of characters, followed by '=>', followed by a space character, followed by any number of characters". And sure enough, this _does_ match " => uvw". Remember that in shell patterns, '*' means 0 more characters, and '?' means exactly one character.
Bash 3.0 supports regular expression matching, but I don't believe that it supports regular expression substitution. To do what you want would require sed.
However, I just checked the bash man page (under 'Pattern Matching'), and learned about composite patterns. These require that extglob be set (use the 'shopt' command to work with these), but they would provide something like:
Code:${st/*([[:space:]])=>*([[:space:]])/,}DISTRO=Arch
Registered Linux User #388732
- 07-11-2007 #6Just Joined!
- Join Date
- Jul 2007
- Posts
- 4
EUREKA!!!
I found the solution
I don't know why it works but It works:
------------test2.sh------------------------
#!/bin/bash
st="xyz => uvw"
echo "${st//[[:space:]]*=>*[[:space:]]/,}"
-------------------------------------------
I have the output I want:
--------- output ------------
$ ./test2.sh
xyz,uvw
-----------------------------
thank you Cabhan for your help, I hope the solution I found can help you
in the future.
bye Andrea.
- 07-11-2007 #7Just Joined!
- Join Date
- Jul 2007
- Posts
- 4
Hi script bash user ...
please look my previous post ... this is an half success because
my previous script it works only .. if are present spaces " " around the
"=>" substring.
------------test2.sh------------------------
#!/bin/bash
st1="xyz => uvw"
st2="xyz=> uvw"
echo "${st1//[[:space:]]*=>*[[:space:]]/,}"
echo "${st2//[[:space:]]*=>*[[:space:]]/,}"
-------------------------------------------
--------- output ------------
$ ./test2.sh
xyz,uvw
xyz=> uvw
-----------------------------
My previous script it works only for st1 and not for st2
- 07-11-2007 #8
Yes. As I said in my last post, '*' here does not mean '0 more more of the preceding', but rather represents characters in its own right. Which means that [[:space:]] is standing for one space character.
To get around this, you need to somehow apply a quantifier to the [[:space:]]. You can do this either by setting extglob with shopt and using *(...) (as I explained in my last post), or using an external tool like sed.
Also, for the record, precisely because this is a shell pattern, your current '*'s do not help. For instance, your current pattern: /[[:space:]]*=>*[[:space:]]/ will match ' a=>hello '. Which you obviously don't want it to.DISTRO=Arch
Registered Linux User #388732
- 07-11-2007 #9Linux Enthusiast
- Join Date
- Aug 2006
- Posts
- 631
As mentioned by Cabhan sed is the tool for this job, to replace spaces or/and tabs by a comma you can try this:
The asterix behind the classes matches for zero or more tabs or spaces.Code:echo "$st"|sed 's/[[:blank:]]*=>[[:blank:]]*/,/'
Regards


Reply With Quote