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

Can sed make something like :

12345

become :

1&2&3&4&5

?

Asked By: user243633

||

Use sed

sed 's/./&&/g;s/.$//'
Answered By: αғsнιη

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:.(?=.))/&}

(~(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 () and &)

Or:

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

(replace every character (?) with & and itself (), 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)).

Answered By: Stéphane Chazelas

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 &)

Answered By: zeppelin

This will be a little slower than some of the other answers, but it’s pretty clear:

echo 12345 | perl -lnE 'say join "&", split //'
Answered By: glenn jackman
sed 's/B/&/g'

B – Matches everywhere but on a word boundary; that is it matches if the character to the left and the character to the right are either
both “word” characters or both “non-word” characters.

Information: GNU sed manual, regular expression extensions.

Testing:

sed 's/B/&/g' <<< '12345'
1&2&3&4&5
Answered By: MiniMax

Here’s another way. The first part of the sed expression captures every character then replaces that with the character and an ampersand. The second part removes the ampersand from the end of the line.

echo 12345 | sed -r 's/(.)/1&/g;s/&$//g'
1&2&3&4&5

Works on multibyte characters too.

Answered By: Alexander
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.