LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   string manipulation in a script file (http://www.linuxquestions.org/questions/linux-general-1/string-manipulation-in-a-script-file-811499/)

mahmoodn 06-01-2010 10:53 AM

string manipulation in a script file
 
I have a string like $(SOMETHING) and want to remove '(' and ')' in a script file. How can I do that? I read that sed command is a filtering utility but don't know how to use it.

colucix 06-01-2010 11:05 AM

Sed is a command line editor. Basically it parses a text and do actions based on regular expressions. The 's' command is one of the more used in one-liners: in this case you can substitute every occurrence of '(' and ')' with nothing, e.g.
Code:

string='$(SOMETHING)'
string=$(echo $string | sed 's/[()]//g')

Without sed you can use the shell's substring replacement, but you need two passes:
Code:

string='$(SOMETHING)'
string=${string/(/}
string=${string/)/}

To learn about sed, here is a must-read: http://www.grymoire.com/Unix/Sed.html

catkin 06-01-2010 11:50 AM

If the string is in a bash variable and SOMETHING does not include any "(" or ")" you can do it with two bash parameter expansions like this
Code:

string='$(SOMETHING)'
string=${string/(/}
string=${string/)/}

That will run faster than using sed (which may be insignificant) but the sed solution is arguably more legible.

EDIT: Ooops! Colucix already wrote that :)

EDIT 2: Now, new, improved! In a single command
Code:

string=${string//[()]/}

cola 06-01-2010 12:03 PM

Quote:

Originally Posted by catkin (Post 3988896)
If the string is in a bash variable and SOMETHING does not include any "(" or ")" you can do it with two bash parameter expansions like this
Code:

string='$(SOMETHING)'
string=${string/(/}
string=${string/)/}

That will run faster than using sed (which may be insignificant) but the sed solution is arguably more legible.

EDIT: Ooops! Colucix already wrote that :)

EDIT 2: Now, new, improved! In a single command
Code:

string=${string//[()]/}

Can't understand how it works.
Code:

string=${string//[()]/}

mahmoodn 06-01-2010 12:54 PM

Code:

string=$(echo $string | sed 's/[()]//g')
and
Code:

string=${string//[()]/}
are the same, however the syntax of the second is complex for me...

Thank you all :)

David the H. 06-01-2010 01:17 PM

What's so difficult to understand? It's all explained in the link catkin provided.

${variable}

The full form of $variable, necessary in some complex situations.

${variable//foo/bar}

Replace all instances of "foo" with "bar" in the variable when expanding it.

[]

Allows groupings of multiple characters. [ABC] would mean A or B or C.

So ${string//[()]/} simply means "replace all instances of ( or ) with nothing when outputting $string, exactly like in the sed statement.

cola 06-01-2010 06:44 PM

This should have been like this:
Code:

string=${string/[()]//}

David the H. 06-01-2010 10:58 PM

Quote:

Originally Posted by cola (Post 3989351)
This should have been like this:
Code:

string=${string/[()]//}

Um, why? :confused: This version replaces only the first parenthesis found with a slash. It's a version of ${variable/foo/bar}, which only replaces one instance, like sed without the global 'g' command.

Code:

$ variable="this is a (foo) (bar) string"

$ echo "${variable/[()]//}"
this is a /foo) (bar) string

$ echo "${variable//[()]/}"
this is a foo bar string

Edit: Maybe you're getting it confused with the sed syntax. Unlike sed, there's no final slash. Only the ending '}' bracket. And instead of 's' at the front and 'g' at the end, there are one or two slashes at the beginning.

Code:

echo "${variable/foo/bar}"  =  echo "$variable | sed 's/foo/bar/'"
echo "${variable//foo/bar}"  =  echo "$variable | sed 's/foo/bar/g'"


colucix 06-02-2010 01:47 AM

Quote:

Originally Posted by catkin (Post 3988896)
Code:

string=${string//[()]/}

Yesss! I always forget about that! :doh:

cola 06-02-2010 02:12 AM

Quote:

Originally Posted by David the H. (Post 3989538)
Um, why? :confused: This version replaces only the first parenthesis found with a slash. It's a version of ${variable/foo/bar}, which only replaces one instance, like sed without the global 'g' command.

Code:

$ variable="this is a (foo) (bar) string"

$ echo "${variable/[()]//}"
this is a /foo) (bar) string

$ echo "${variable//[()]/}"
this is a foo bar string

Edit: Maybe you're getting it confused with the sed syntax. Unlike sed, there's no final slash. Only the ending '}' bracket. And instead of 's' at the front and 'g' at the end, there are one or two slashes at the beginning.

Code:

echo "${variable/foo/bar}"  =  echo "$variable | sed 's/foo/bar/'"
echo "${variable//foo/bar}"  =  echo "$variable | sed 's/foo/bar/g'"


Isn't the form to replace string:
Code:

st="bgerretsberger"
st=${st/et/zz}
echo ${st}

It's common for sed witout g and for vim too.

David the H. 06-02-2010 07:34 AM

Quote:

Originally Posted by cola (Post 3989690)
Isn't the form to replace string:
Code:

st="bgerretsberger"
st=${st/et/zz}
echo ${st}

It's common for sed witout g and for vim too.

Please read the link and my previous post again and pay careful attention to the syntax.

One slash at the front is for a single replacement.
Two slashes at the front is for a global replacement.

It's the same as the difference between sed "s///" and sed "s///g"

Since the opening poster wanted to have all parentheses removed, he'd have to use the two-slash version.

In fact, if all you want to do is remove a substring, you don't even need the final slash. The replacement will automatically be "nothing".

Code:

$ variable="this is a foo foo foo string"

$ echo "${variable/foo }"  #note the space at the end
this is a foo foo string

$ echo "${variable//foo }"
this is a string

$ echo "${variable/foo /bar }"
this is a bar foo foo string

$ echo "${variable//foo /bar }"
this is a bar bar bar string

### Now with sed:

$ echo "$variable" | sed 's/foo //'
this is a foo foo string

$ echo "$variable" | sed 's/foo //g'
this is a string

$ echo "$variable" | sed 's/foo /bar /'
this is a bar foo foo string

$ echo "$variable" | sed 's/foo /bar /g'
this is a bar bar bar string

Just try it for yourself if you aren't convinced.

cola 06-02-2010 10:17 AM

Quote:

Originally Posted by David the H. (Post 3989538)
Um, why? :confused: This version replaces only the first parenthesis found with a slash. It's a version of ${variable/foo/bar}, which only replaces one instance, like sed without the global 'g' command.

Code:

$ variable="this is a (foo) (bar) string"

$ echo "${variable/[()]//}"
this is a /foo) (bar) string

$ echo "${variable//[()]/}"
this is a foo bar string

Edit: Maybe you're getting it confused with the sed syntax. Unlike sed, there's no final slash. Only the ending '}' bracket. And instead of 's' at the front and 'g' at the end, there are one or two slashes at the beginning.

Code:

echo "${variable/foo/bar}"  =  echo "$variable | sed 's/foo/bar/'"
echo "${variable//foo/bar}"  =  echo "$variable | sed 's/foo/bar/g'"


Why does it change only the first '(' character?
And why is it replaced with '/'?

David the H. 06-02-2010 01:39 PM

Figure it out.

${variable/[()]//}

"variable slash X slash Y".

So what is X, and what is Y, in the example above?

And what did I just say about the difference between having one slash and two in the first position?


All times are GMT -5. The time now is 09:26 AM.