Search code examples
shellperlsed

Match pattern and insert this pattern after every character until end of line


I've got a line with an identifier, then a pattern (in my case, a semicolon) and then a list of numbers:

echo "sp16;111111111111111111111111111111211" 

I'd like to insert a semicolon between all numbers as in (desired output):

echo "sp16;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;2;1;1"

So far, I found how to insert a semicolon between all characters using sed:

sed 's/.\{1\}/&;/g'

But, then it also inserts semicolons before matching the first semicolon and also it adds a semicolon ad the end of the line.


Solution

  • With a Perl's one-liner:

    perl -pe 's/^([^;]+;)([0-9]+)/$1 . join ";", split "", $2/e' file
    

    sp16;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;2;1;1
    

    The regular expression matches as follows:

    Node Explanation
    ^ the beginning of the string anchor
    ( group and capture to \1:
    [^;]+ any character except: ; (1 or more times (matching the most amount possible))
    ; ;
    ) end of \1
    ( group and capture to \2:
    [0-9]+ any character of: '0' to '9' (1 or more times (matching the most amount possible))
    ) end of \2

    Perl's code explanations

    Operator Meaning
    $1 captured group 1 like \1 in sed
    . concatenation
    join ";", join with the character ';' the following list...
    split "", $2 split captured group $2 or \2 in a list of digits
    e modifier that allow Perl's code/expression in the right part of substitution s///