6

In Linux, if I have a file with entries like:

My Number is = 1234; #This is a random number

Can I use sed or anything else to replace all spaces after '#' with '+', so that the output looks like:

My Number is = 1234; #This+is+a+random+number

5 Answers 5

3

One way using awk:

awk -F# 'OFS=FS { gsub(" ", "+", $2) }1' file.txt

Result:

My Number is = 1234; #This+is+a+random+number

EDIT:

After reading comments below, if your file contains multiple #, you can try this:

awk -F# 'OFS=FS { for (i=2; i <= NF; i++) gsub(" ", "+", $i); print }' file.txt
Sign up to request clarification or add additional context in comments.

6 Comments

The 1 is an expression that evaluates to true, causing the current line to be printed. It's a short-cut for {print}.
While this answer is a nice example of awk, I'm not 100% sure it meets the OP's requirements. What if there is another # in the line?
replace gsub(" ", "+", $2) with for (i=2;i<=NF;++i) gsub(" ", "+", $i) and it will handle any number of # chars
Also, the 1 trick is nice for code golf, but in general I think a simple ; print inside the curlies would be clearer.
@ghoti, Point noted. I made some assumptions about the OP's input.
|
3

You can do this in pure shell...

$ foo="My Number is = 1234; #This is a random number"
$ echo -n "${foo%%#*}#"; echo "${foo#*#}" | tr ' ' '+'
My Number is = 1234; #This+is+a+random+number
$ 

Capturing this data to variables for further use is left as an exercise for the reader. :-)

Note that this also withstands multiple # characters on the line:

$ foo="My Number is = 1234; #This is a # random number"
$ echo -n "${foo%%#*}#"; echo "${foo#*#}" | tr ' ' '+'
My Number is = 1234; #This+is+a+#+random+number
$ 

Or if you'd prefer to create a variable rather than pipe through tr:

$ echo -n "${foo%%#*}#"; bar="${foo#*#}"; echo "${bar// /+}"
My Number is = 1234; #This+is+a+#+random+number

And finally, if you don't mind subshells with pipes, you could do this:

$ bar=$(echo -n "$foo" | tr '#' '\n' | sed -ne '2,$s/ /+/g;p' | tr '\n' '#')
$ echo "$bar"
My Number is = 1234; #This+is+a+#+random+number
$

And for the fun of it, here's a short awk solution:

$ echo $foo | awk -vRS=# -vORS=# 'NR>1 {gsub(/ /,"+")} 1'
My Number is = 1234; #This+is+a+#+random+number
#$ 

Note the trailing ORS. I don't know if it's possible to avoid a final record separator. I suppose you could get rid of that by piping the line above through head -1, assuming you're only dealing with the one line of input data.

1 Comment

I think that to use awk, you'd have to do the for loop as steve proposed.
2

Not terrible efficient, but:

perl -pe '1 while (s/(.*#[^ ]*) /\1+/);'

Comments

2

This might work for you (GNU sed):

echo 'My Number is = 1234; #This is a random number' | 
sed 's/#/\n&/;h;s/.*\n//;y/ /+/;H;g;s/\n.*\n//'
My Number is = 1234; #This+is+a+random+number

2 Comments

+1 - Great, I was hoping somebody would demonstrate this with a hold buffer. :) Alas, in BSD sed it breaks badly if there's a second # on the line. (But you did mention GNU, so you keep your +1!)
@ghoti thanks, I'm surprised that a second # causes a problem (even for BSD). Usually the \n's are the ones at fault in other sed's. Could you have added a g to the substitute command in translation?
1

Here is yet another perl one-liner:

echo 'My Number is = 1234; #This is a random number' \
| perl -F\# -lane 'join "#", @F[1,-1]; s/ /+/g; print $F[1], "#", $_'
  • -F specifies how to split string into @F array.
  • -an wraps stdin with:
while (<>) {
  @F = split('#');
  # code from -e goes here
}

3 Comments

It also breaks if there are extra # characters. Try it with: 'My Number is = 1234; #This is a random # number to see.
Right forgot about the separator, will fix it shortly.
The fix maintains the first separator, but still doesn't help with the alternate string I posted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.