In `sed` how can I put one "&" between characters in a string?

With GNU sed:

sed 's/./\&&/2g'

(substitute every (g) character (.) with the same (&) preceded with & (\&) but only starting from the second occurrence (2)).

Portably:

sed 's/./\&&/g;s/&//'

(replace every occurrence, but then remove the first & which we don't want).

With some awk implementations (not POSIX as the behaviour is unspecified for an empty FS):

awk -F '' -v OFS="&" '{$1=$1;print}'

(with gawk and a few other awk implementations, an empty field separator splits the records into its character constituents. The output field separator (OFS) is set to &. We assign a value to $1 (itself) to force the record to be regenerated with the new field separator before printing it, NF=NF also works and is slightly more efficient in many awk implementations but the behaviour when you do that is currently unspecified by POSIX).

perl:

perl -F -lape '$_=join"&",@F' 

(-pe runs the code for every line, and prints the result ($_); -l strips and re-adds line endings automatically; -a populates @F with input split on the delimiter set in -F, which here is an empty string. The result is to split every character into @F, then join them up with '&', and print the line.)

Alternatively:

perl -pe 's/(?<=.)./&$&/g' 

(replace every character provided it's preceded by another character (look-behind regexp operator (?<=...))

Using zsh shell operators:

in=12345
out=${(j:&:)${(s::)in}}

(again, split on an empty field separator using the s:: parameter expansion flag, and join with &)

Or:

out=${in///&} out=${out#?}

(replace every occurrence of nothing (so before every character) with & using the ${var//pattern/replacement} ksh operator (though in ksh an empty pattern means something else, and yet something else, I'm not sure what in bash), and remove the first one with the POSIX ${var#pattern} stripping operator).

Using ksh93 shell operators:

in=12345
out=${in//~(P:.(?=.))/\0&}

(~(P:perl-like-RE) being a ksh93 glob operator to use perl-like regular expressions (different from perl's or PCRE's though), (?=.) being the look-ahead operator: replace a character provided it's followed by another character with itself (\0) and &)

Or:

out=${in//?/&\0}; out=${out#?}

(replace every character (?) with & and itself (\0), and we remove the superflous one)

Using bash shell operators:

shopt -s extglob
in=12345
out=${in//@()/&}; out=${out#?}

(same as zsh's, except that you need @() there (a ksh glob operator for which you need extglob in bash)).


Unix utilities:

fold -w1|paste -sd\& -

Explained:

"fold -w1" - will wrap an each input character to its own line

fold - wrap each input line to fit in specified width

-w, --width=WIDTH use WIDTH columns instead of 80

%echo 12345|fold -w1
1
2
3
4
5

"paste -sd\& -" - will merge the input lines together, using & as a separator

paste - merge lines of files

-s, --serial paste one file at a time instead of in parallel

-d, --delimiters=LIST reuse characters from LIST instead of TABs

%fold -w1|paste -sd\& -
1&2&3&4&5

(Note that if the input contains several lines, they'll be joined with &)


Use sed

sed 's/./&\&/g;s/.$//'