3

I have a file that contains numbers copied from somewhere. It looks something like this:

{02   12     04 01 07 10 11 06 08 05 03    15     13     00    14     09},
{14   11     02 12 04 07 13 01 05 00 15    10     03     09    08     06},
{04   02     01 11 10 13 07 08 15 09 12    05     06     03    00     14},
{11   08     12 07 01 14 02 13 06 15 00    09     10     04    05     03}

I now have to add comma after every number (basically to make it a C++ array). I tried using sed:

cat file.txt | sed -r "s/ /, /g"

But this prefixes every space with a comma, while I only want them after digits.

If I use cat file.txt | sed -r "s/[0123456789] /, /g", I won't be able to get the same number before replacement. Thus, I only want to change some part of the substring.

How do I do this?

3
  • 1
    @Hello scipsycho. Please see below. is this what you want?
    – user88036
    Commented Sep 27, 2018 at 16:14
  • Just a heads-up: It won't compile even with commas. 08 and 09 are not valid integer literals.
    – pipe
    Commented Sep 28, 2018 at 1:58
  • 2
    @pipe you are right! but now that you guys have answered this question, I will do cat file.txt | sed -r 's/([{, ])0+([0-9])+/ \1 \2/g' which will remove any zeros occurring in the units place
    – scipsycho
    Commented Sep 28, 2018 at 2:48

4 Answers 4

6
cat file.txt | sed -r 's/([0-9]+)/\1,/g'

{02,   12,     04, 01, 07, 10, 11, 06, 08, 05, 03,    15,     13,     00,    14,     09,},
{14,   11,     02, 12, 04, 07, 13, 01, 05, 00, 15,    10,     03,     09,    08,     06,},
{04,   02,     01, 11, 10, 13, 07, 08, 15, 09, 12,    05,     06,     03,    00,     14,},
{11,   08,     12, 07, 01, 14, 02, 13, 06, 15, 00,    09,     10,     04,    05,     03,}

Explanation:

First capturing group ([0-9]+)

Match a single character (i.e. number) present in the table [0-9]+ 
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
0-9 a single character in the range between 0 (index 48) and 9 (index 57) (case sensitive)

In other words, the [0-9]+ pattern matches an integer number (without decimals) even Inside longer strings, even words.
\1 is called a "back reference" or "special escapes" in the sed documentation. It refers to the corresponding matching sub-expressions in the regexp. In other words, in this example, it inserts the contents of each captured number in the table followed by comma.
7
  • 1
    Thanks! it worked! What does this '\1' mean?
    – scipsycho
    Commented Sep 27, 2018 at 16:27
  • Hi @scipsycho. ` \1` refers to the number within each cell in the field will be followed by a comma. :-)
    – user88036
    Commented Sep 27, 2018 at 16:34
  • 1
    Hi @Goro, thanks a lot for this explanation.
    – scipsycho
    Commented Sep 27, 2018 at 16:49
  • 2
    The \1 is called a "back reference" in the sed documentation.
    – RobertL
    Commented Sep 27, 2018 at 16:50
  • 2
    sed can read files.
    – RudiC
    Commented Sep 27, 2018 at 21:24
3

You can just replace a space followed by any number of spaces by a comma:

sed 's/  */,/g' file

(if the spaces at the start of some lines are just a copy paste error)

2

How about

sed 's/ \+/, /g' file
{02, 12, 04, 01, 07, 10, 11, 06, 08, 05, 03, 15, 13, 00, 14, 09},
{14, 11, 02, 12, 04, 07, 13, 01, 05, 00, 15, 10, 03, 09, 08, 06},
{04, 02, 01, 11, 10, 13, 07, 08, 15, 09, 12, 05, 06, 03, 00, 14},
{11, 08, 12, 07, 01, 14, 02, 13, 06, 15, 00, 09, 10, 04, 05, 03}
1

This perl command will add a comma in between a digit and a space

perl -pe 's/(?<=\d)(?=\s)/,/g' file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .