I have a number -> 12345
I want output in below format
1+2+3+4+5
echo `cat fl.txt | paste -s -d ''`
gives only 12345
.
But when I add this + at the below command it gives same 12345
.
echo `cat fl.txt | paste -s -d '' | tr -s '' '+'`
I have a number -> 12345
I want output in below format
1+2+3+4+5
echo `cat fl.txt | paste -s -d ''`
gives only 12345
.
But when I add this + at the below command it gives same 12345
.
echo `cat fl.txt | paste -s -d '' | tr -s '' '+'`
It's easier to split a string into characters:
fold -w1 file | paste -sd+ -
Some versions of the fold
command do not have the -c
option but have the -w
option. In this case, they will be interchangeable.
or:
grep -o '.' file | paste -sd+ -
Perhaps with one command:
awk -v OFS='+' -F '' '{$1=$1; print}' file
And:
sed 's/\B/+/g' file
With zsh
:
$ number=12345
$ printf '%s\n' ${(j[+])${(s[])number}}
1+2+3+4+5
s[]
parameter expansion flag to split $number
into its character components. j[+]
to join them back with +
.
With bash
:
$ number=12345
$ shopt -s extglob
$ tmp=${number//@()/+}
$ printf '%s\n' "${tmp#+}"
1+2+3+4+5
${number//@()/+}
replaces all the occurrences of nothing with +
. For some reason ${number///+}
doesn't seem to work in bash
(it works in zsh
though).
If you're loooking for shell-only, this is bash:
input=1245
output=""
while IFS= read -r -n1 char; do output+="${char}+"; done < <(printf %s "$input")
output=${output%+}
echo "$output" # => 1+2+4+5
The odd looking < <(printf %s "$input")
is a process substitution that redirects the input, with no trailing newline, into the while-read loop.
Or sed
output=$( sed 's/./&+/g; s/+$//' <<<"$input")
read
approach assumes $input
contains no character of $IFS
nor newlines.
Oct 25, 2020 at 15:33
just some other possibilities using perl instead of awk or sed:
echo 12345 | perl -lpe '$_ = join "+", split //;'
or (if the number is saved in fl.txt
)
# echo 12345 > fl.txt
perl -lpe '$_ = join "+", split //;' fl.txt
the -l
param just avoids the line ending being included (when joining with "+"). otherwise you'd have 1+2+3+4+5+
as result.
alternatively you can use the method, similar as the one mentioned for sed already:
perl -pe 's/.\K/+/g; s/\+$//;' fl.txt
or
perl -pe 's/.\K(?!$)/+/g;' fl.txt
or
perl -pe 's/\B/+/g;' fl.txt
output in all cases:
1+2+3+4+5
There are lots of ways to do this. On way is to use Ruby to split your string into characters, and then join them back together with the +
symbol. For example, at the shell prompt:
$ ruby -e 'puts ARGV.first.chars.join "+"' 12345
1+2+3+4+5
Using Raku (formerly known as Perl_6)
~$ echo 12345 | raku -ne 'put .comb.join("+");'
1+2+3+4+5
#OR
~$ echo 12345 | raku -pe '.=comb; .=join("+");'
1+2+3+4+5
Raku is a programming language in the Perl-family of programming languages. The code above uses Raku's new comb
routine, which sifts through the input text to break around (and select out) a desired sequence, converse to the action of the split
operator. Without any parameters, comb()
breaks before/after each character. Here, because the target sequence is digits, comb(/ \d /)
might prove useful:
% echo abcd12345efgh | raku -ne 'put .comb(/ \d /).join("+");'
1+2+3+4+5
#OR
% echo abcd12345efgh | raku -pe '.=comb(/ \d /); .=join("+");'
1+2+3+4+5
This isn't to say that other options aren't available. Below are solutions in a similar vein to the excellent Perl solutions posted by @uvularer_frikativ:
~$ echo 12345 | raku -pe '$_ = join "+", .split: "", :skip-empty;'
1+2+3+4+5
#OR
~$ echo 12345 > 12345.txt
~$ raku -pe '$_ = join "+", .split: "", :skip-empty;' 12345.txt
1+2+3+4+5
Some more Raku options:
~$ raku -pe 's:g/ )> . /+/; s/^\+//;' 12345.txt
1+2+3+4+5
#OR
~$ raku -pe 's:g/<!after ^> )> . /+/;' 12345.txt
1+2+3+4+5
#OR
~$ raku -pe 's:g/ <?after . > <!before $ > /+/;' 12345.txt
1+2+3+4+5
#OR
~$ raku -pe 's:g/<ww>/+/;' 12345.txt
1+2+3+4+5