LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Shell script: I have string "abc____def____ghi", how to make "abc def ghi" (http://www.linuxquestions.org/questions/programming-9/shell-script-i-have-string-abc____def____ghi-how-to-make-abc-def-ghi-794291/)

vouser 03-09-2010 02:26 PM

Shell script: I have string "abc____def____ghi", how to make "abc def ghi"
 
It's silly, but I could not find examples for this.
I need to replace N number of _ with N number of spaces.
It always makes me "abc def ghi". (One space gap)
Thanks to all.

druuna 03-09-2010 02:49 PM

Hi,

Is this what you want:
Code:

echo $foo
abc____def____ghi

$ echo $foo | sed 's/_/ /g'
abc    def    ghi

Hope this helps.

vouser 03-09-2010 03:09 PM

Thank you very much for trying to help me.
Here are more details on my issue.

I have a script with a variable:

msg_string='01009999888811000001E00000001000099999988881004102099999999999900__USA_________123456789 012345'

I need a code that replaces all underscores with blanks preserving the length of the message.

I ran your code and it gave me:
01009999888811000001E00000001000099999988881004102099999999999900 USA 123456789012345

As you see, we altered the message length.

Thanks again,
vouser.

MTK358 03-09-2010 03:12 PM

Quote:

Originally Posted by druuna (Post 3891981)
Hi,

Is this what you want:
Code:

echo $foo
abc____def____ghi

#      V    V
$ echo "$foo" | sed 's/_/ /g'
abc    def    ghi

Hope this helps.

Use quotes, otherwise bash interprets the spaces as argument separators.

druuna 03-09-2010 03:26 PM

Hi,

@MTK358: There are no spaces in the input ;)

@vouser: If you apply my solution I do think you have what you want:
Code:

$ foo='01009999888811000001E00000001000099999988881004102099999999999900__USA_________123456789 012345'
$ echo $foo
01009999888811000001E00000001000099999988881004102099999999999900__USA_________123456789 012345
$ echo $foo | sed 's/_/ /g'
01009999888811000001E00000001000099999988881004102099999999999900  USA        123456789 012345

That is what you ask:
Quote:

I need a code that replaces all underscores with blanks preserving the length of the message.
Hope this helps.

MTK358 03-09-2010 03:49 PM

Quote:

Originally Posted by druuna (Post 3892018)
There are no spaces in the input ;)

Oh, I just got a little confused.

I would still use the braces in case the string contains bash special chars, though.

vouser 03-09-2010 04:41 PM

Gentlemen:

thanks for your help:

Here's my working function:

fn_send_msg(){
msg_out=`msg_get 1``msg_get 2``msg_get 3``msg_get 4``msg_get 12``msg_get 13``msg_get 14``msg_get 18``msg_get 37``msg_get 39``msg_get 59``msg_get 62`
echo "Msg before replacing:"
echo $msg_out

#msg_out=`echo $msg_out | sed 's/_/ /g'` #~ OK
msg_out="${msg_out//_/ }" #~ OK
echo "Msg out:"
echo "$msg_out"

#~ Open socket ~~~~~~~~~~~~~~~~~~~~
exec 3<>/dev/tcp/172.26.0.103/9991

#~ Send msg ~~~~~~~~~~~~~~~~~~~~~~~
echo "$msg_out" >&3

#~ Receive msg ~~~~~~~~~~~~~~~~~~~~
read -r msg_in <&3
echo "Msg in:"
echo "$msg_in" # OK
}

What I've learned is that there is a difference between:

echo $msg

and

echo "$msg"

if msg has blanks.

Regards,
vouser

ghostdog74 03-09-2010 08:20 PM

since you are using bash, you can use this function to replace your strings without calling external commands.

Code:

repl(){
  mystring="$1"
  r="$2"
  sub="$3"
  echo "${mystring//$r/$sub}" #thanks to catkin jolting my memory to quote my variables

}

use it like this in your script.
Code:

repl "abc____def____ghi__end" "_" " "

catkin 03-09-2010 10:01 PM

Bash's Parameter Expansion can do the job quite cleanly:
Code:

c@CW8:~$ string='abc____def____ghi'
c@CW8:~$ echo "${string//_/ }"
abc    def    ghi

From the link above:

${parameter/pattern/string} The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. If pattern begins with /, all matches of pattern are replaced with string. Normally only the first match is replaced.


All times are GMT -5. The time now is 06:31 PM.