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
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
1 is an expression that evaluates to true, causing the current line to be printed. It's a short-cut for {print}.# in the line?gsub(" ", "+", $2) with for (i=2;i<=NF;++i) gsub(" ", "+", $i) and it will handle any number of # chars1 trick is nice for code golf, but in general I think a simple ; print inside the curlies would be clearer.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.
for loop as steve proposed.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
# on the line. (But you did mention GNU, so you keep your +1!)# 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?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
}
# characters. Try it with: 'My Number is = 1234; #This is a random # number to see.