3

I have a file that contains a 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) but as you can see it can be very tedious to do, especially if you have many of them.

I tried using sed like:
cat file.txt | sed -r "s/ /, /g"

But if I use this I am going to replace every "space" with ',space' and I only want to replace spaces that come after a digit with ','

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?

  • 1
    @Hello scipsycho. Please see below. is this what you want? – user88036 Sep 27 '18 at 16:14
  • Just a heads-up: It won't compile even with commas. 08 and 09 are not valid integer literals. – pipe Sep 28 '18 at 1:58
  • @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 Sep 28 '18 at 2:48
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.
  • 1
    Thanks! it worked! What does this '\1' mean? – scipsycho Sep 27 '18 at 16:27
  • Hi @scipsycho. ` \1` refers to the number within each cell in the field will be followed by a comma. :-) – user88036 Sep 27 '18 at 16:34
  • 1
    Hi @Goro, thanks a lot for this explanation. – scipsycho Sep 27 '18 at 16:49
  • 2
    The \1 is called a "back reference" in the sed documentation. – RobertL Sep 27 '18 at 16:50
  • 2
    sed can read files. – RudiC Sep 27 '18 at 21:24
2

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.