Reputation: 143
I need to replace a selected character with as many copies of another character as necessary to fill up a determined space (exact 12 chars).
Example, replace char '1' with zero or more char '0':
ABC1 => ABC000000000
ABC1JKL => ABC000000JKL
1JKL => 000000000JKL
1000 => 000000000000
ABCDEFGHIJKL1 => ABCDEFGHIJKL
1ABCDEFGHIJKL => ABCDEFGHIJKL
ABCDEFGHIJKL => ABCDEFGHIJKL
1EFG1 => undefined (do not bother with this case)
EFG => undefined (do not bother with this case)
Upvotes: 1
Views: 426
Reputation: 5763
A solution in awk:
{
temp = $1
gsub (/[^1]/, "", temp)
if (length(temp) == 1) {
l = 12 - (length ($1) - 1)
if (l > 0) {
t = "000000000000"
sub (/1/, substr (t,0,l), $1)
}
}
print $1
}
And a solution in bash/sed:
#!/bin/bash
while read n; do
temp=$(echo $n | sed 's/[^1]//g')
if [[ ${#temp} == 1 ]]; then
l=$(( 12 - $(( ${#n} - 1)) ))
if [[ $l > 0 ]]; then
t=000000000000
n=$(echo $n | sed "s/1/${t:0:$l}/")
fi
fi
echo $n
done
Upvotes: 1
Reputation: 46883
Since everybody is giving his own personal answer, here's my own brew (100% pure bash), probably a good candidate for a code-golf (and also probably one of the most efficient — no loop, no pipe, only one subshell (see end of post to get rid of it)):
$ string="ABC1"
$ echo "${string/1/$(printf "%.$((13-${#string}))d" 0)}"
ABC000000000
Do I win?
If you just can't believe that this one liner works, here you go:
$ while read string; do printf "%s%$((13-${#string}))s => %s\n" "$string" '' "${string/1/$(printf "%.$((13-${#string}))d" 0)}"; done < <(printf "%s\n" ABC1 ABC000000000 ABC1JKL 1JKL 1000 ABCDEFGHIJKL1 1ABCDEFGHIJKL ABCDEFGHIJKL 1EFG1 EFG)
ABC1 => ABC000000000
ABC000000000 => ABC000000000
ABC1JKL => ABC000000JKL
1JKL => 000000000JKL
1000 => 000000000000
ABCDEFGHIJKL1 => ABCDEFGHIJKL
1ABCDEFGHIJKL => ABCDEFGHIJKL
ABCDEFGHIJKL => ABCDEFGHIJKL
1EFG1 => 00000000EFG1
EFG => EFG
$ string="ABC1"
$ printf -v aux "%.$((13-${#string}))d" 0
$ echo "${string/1/$aux}"
ABC000000000
Upvotes: 1
Reputation: 242123
Using bash's Parameter expansion:
#! /bin/bash
inputs=(ABC1
ABC1JKL
1JKL
1000
ABCDEFGHIJKL1
1ABCDEFGHIJKL
ABCDEFGHIJKL
)
outputs=(ABC000000000
ABC000000JKL
000000000JKL
000000000000
ABCDEFGHIJKL
ABCDEFGHIJKL
ABCDEFGHIJKL
)
for ((i=0; i<${#inputs[@]}; i++)) ; do
x=${inputs[i]}
while [[ ${x:12} ]] ; do # Shorten if too long
x=${x/1}
done
while [[ ${x:11} == '' ]] ; do # Insert 1's if too short
x=${x/1/11}
done
x=${x//1/0}
[[ $x == ${outputs[i]} ]] || echo Different $x
done
Upvotes: 1