0

I want to use sed to replace something like $some latex$ or

$$
some latex
$$

with {% math %}some latex {% endmath %} or

{% math %}
some latex
{% endmath %}

I try sed to solve this problem but a command like

sed -e 's/\$\([^\$]\{1,\}\)\$/{% math %}\1{% endmath %}/g' filename

doesn't work for $some latex$ and I don't know how to deal with multi-line. How can I do this?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
modkzs
  • 1,369
  • 4
  • 13
  • 17
  • 1
    In general, `sed` is not the right tool for this. Something as simple `$ \$ $` would break any tool that does not actually understand LaTeX syntax. – chepner Mar 05 '16 at 16:54
  • It is not quite clear if `$some latex$` is on a line on its own (probably not) - a real example of what your input looks like would go a long way. And is `$$` always on a separate line? And there are no `\[ \]` anywhere to replace? – Benjamin W. Mar 06 '16 at 05:46

2 Answers2

1

The only problem you are facing here is capturing newline or whitespace, which is solved by following regex.

Regex: (?:\$*)(\s*)some latex(\s*)(?:\$*)

Flags used:

  • g for global search.

Explanation:

  • (?:\$*)(\s*) captures the whitespace or newline after leading $ or $$

  • (\s*)(?:\$*) captures the whitespace or newline before trailing $ or $$

Replacement to do: {% math %}\1some latex\2{% endmath %}

Regex101 Demo

  • There may some misunderstanding. What's inside $ is latex code like P_{ij}, and is not the string "some latex". For example, I would like to replace $ in `$P\left\{X_n=j|X_{n-1}=i\right\}=P_{ij}$` – modkzs Mar 06 '16 at 00:17
  • This regex wouldn't work for sed anyway: it doesn't understand non-capturing groups and `\s`. – Benjamin W. Mar 06 '16 at 05:16
  • @modkzs: You didn't clarified that in the question above. We can replace `some latex` with `.*` to match everything in between `$`. And it would do the same job. –  Mar 06 '16 at 05:56
  • @BenjaminW.: I tried to provide a help from regex point of view. This might not be a **complete** solution but will definitely help in developing it. –  Mar 06 '16 at 05:57
1

Try this with sed :

sed -e ' /\$\$/{s/\$\$/{% math %}/;:a;N;/\$\$/!ba;s/\$\$/{% endmath %}/};s/^\(\$\)\(.*\)\(\$\)$/{% math %}\2{% endmath %}/' sourcefile

Multiline is preserved.

Update :

It seems there is a BSD (OS X?) sed issue with semi colons.

It should work replacing it with new lines :

sed -e '
  /\$\$/ {
    s/\$\$/{% math %}/
      :a
      N
      /\$\$/!ba
      s/\$\$/{% endmath %}/;}
      s/^\(\$\)\(.*\)\(\$\)$/{% math %}\2{% endmath %}/
' sourcefile

I also updated the last s command to match lines like $ \$ $ mentioned in you comments.

SLePort
  • 15,211
  • 3
  • 34
  • 44
  • There is some mistake when running it.`sed: 1: " /\$\$/ { s/\$\$/{% mat ...": whitespace after label sed: 1: " /\$\$/ { s/\$\$/{% mat ...": unexpected EOF (pending }'s)` – modkzs Mar 06 '16 at 00:18
  • [This answer](http://stackoverflow.com/questions/24275070/sed-not-giving-me-correct-substitute-operation-for-newline-with-mac-difference/24276470#24276470) is a great overview of GNU/BSD sed differences and how to overcome them. – Benjamin W. Mar 06 '16 at 05:19
  • @BenjaminW. Thanks for the link. There is much more differences than i imagined. I added a `-e` to sed. Hope it will do the trick. – SLePort Mar 06 '16 at 05:39
  • I actually don't think it will, but newlines should go a long way - and "enter code here" is an editing artefact, right? – Benjamin W. Mar 06 '16 at 05:42
  • "The most portable approach is to use POSIX features only". I tried with the --posix GNU option and it works for me. – SLePort Mar 06 '16 at 05:52
  • I get the following message when trying the second approach on Mac `": bad flag in substitute command: '}'` – Jane Wayne May 10 '18 at 03:07
  • You're right @JaneWayne. A missing `;`. I updated the multiline command. – SLePort May 10 '18 at 05:53