Text processing: transforming numbers in equivalent number of spaces in bash

1

I have a file containing strings with embedded macros like

int main() { $(3) return 0; $(0) }

The sequence of characters " $(n) " should be replaced by n white spaces and the end of line character, so that the resulting text looks like this:

int main() {
   return 0;
}

Is there a way to do this using some bash utility, e.g, sed or awk?

Fabio

Posted 2018-01-23T10:57:05.860

Reputation: 143

Answers

1

Here is a perl one-liner that does the job:

perl -ne 's/\s*\$\((\d+)\)\s*/"\n"." "x${1}/eg;print' file.txt

Output:

int main() {
   return 0;
}

Edit according to comment:

perl -ne 's/\s*\$\((\d+)\)\h*(\R)?/"\n"." "x$1.$2/eg;print' file.txt

input file:

int main() { $(3) return 0; $(0) } $(0)
int main() { $(3) return 0; $(0) } $(0)

Output:

int main() {
   return 0;
}

int main() {
   return 0;
}

Explanation:

s/          : substitute
  \s*       : 0 or more spaces
  \$\(      : literally $(
    (\d+)   : group 1, 1 or more digits
  \)        : literally )
  \h*       : 0 or more horizontal spaces
  (\R)?     : group 2, optional, any kind of linebreak
/
  "\n"      : a linebreak
  .         : concatenate with
  " "x$1    : a space that occurs $1 times, $1 is the content of group 1 (ie. the number inside parenthesis)
  .         : concatenate with
  $2        : group 2, linebreak if it exists
/eg         : flag execute & global

Toto

Posted 2018-01-23T10:57:05.860

Reputation: 7 722

Do you know if that is available in sed? I do not have perl on my machine. Thanks. – Fabio – 2018-01-23T12:20:53.960

@Fabio: I'm not very good at sed. I don't know if it is possible to use x operator – Toto – 2018-01-23T12:32:59.367

I installed perl and tried this. It works quite nicely. The only issue is that it dies not convert to a newline a terminating macro. E.g. if in a file I have two identical lines like this one: int main() { $(3) return 0; $(0) } $(0), I would expect the trailing $(0) to introduce an empty line between the two lines, but it does not. Why is that? – Fabio – 2018-01-25T16:05:10.310

@Fabio: see my edit. – Toto – 2018-01-25T17:10:02.317