2

I have a .tex file named a.tex containing many lines of texts like in the following example:

\begin{pycode}

Some text right here, let's say Text 1A: like: There are #cat and #dog.

\end{pycode}

Some text right here, let's say Text 1B: like: One day the #dog tried to run away.


\begin{pycode}

Some text right here, let's say Text 2A: like: There are #cat and #dog and #pig.

\end{pycode}

Some text right here, let's say Text 2B: like: There is #something here.

I want to replace any # by "the number of the mentioned Text", for example, the sentence "There are #cat and #dog." should be turned to "This is a 1dog and 1cat." because it is in Text 1A. And "One day the #dog tried to run away." is turned to "One day the 1dog tried to run away." And "There are #cat and #dog and #pig." is changed to "There are 2cat and 2dog and 2pig.", and so on.

The output is a .tex file with this change applied to the whole document.

So what I want is:

\begin{pycode}

Some text right here, let's say Text 1A: like: There are 1cat and 1dog.

\end{pycode}

Some text right here, let's say Text 1B: like: One day the 1dog tried to run away.


\begin{pycode}

Some text right here, let's say Text 2A: like: There are 2cat and 2dog and 2pig.

\end{pycode}

Some text right here, let's say Text 2B: like: There is 2something here.

I don't have a minimal work on this. My idea is to search and replace by going from the first line. For example, if we see "begin{pycode}" then s = s+1 (for some counting variable s) and search # then replace it by s until we meet the next "begin{pycode}".

I am searching a solution in this way but still need time to come to a solution.

Thank for any help.

Nam Phan
  • 35
  • 4
  • 2
    This should not be hard to do in Awk; read an introduction. The [Stack Overflow `awk` tag info page](/tags/awk/info) has some links to materials. – tripleee Nov 28 '22 at 08:02
  • 1
    @tripleee I saw that somewhere during my search. Could you pls. point me an example? This is new to me. – Nam Phan Nov 28 '22 at 08:11
  • 2
    Again, the link contains pointers to learning materials. Awk is not a big language, you should be able to figure it out from a basic tutorial. – tripleee Nov 28 '22 at 08:28
  • Get the book Effective AWK Programming, 5th Edition, by Arnold Robbins. – Ed Morton Nov 28 '22 at 10:31

2 Answers2

1
$ awk '/\\begin[{]pycode}/{s++} {gsub(/#/,s); print}' a.tex
\begin{pycode}

Some text right here, let's say Text 1A: like: There are 1cat and 1dog.

\end{pycode}

Some text right here, let's say Text 1B: like: One day the 1dog tried to run away.


\begin{pycode}

Some text right here, let's say Text 2A: like: There are 2cat and 2dog and 2pig.

\end{pycode}

Some text right here, let's say Text 2B: like: There is 2something here.
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
-2

You can use the 'sed' command like this:

sed -e 's/searchFor/replaceWith/g' filename

In your case:

sed -e 's/#/'$i'/g' a.tex > output.tex

What it does is to find all appearances of '#' string inside the a.tex file, replace them with the value of $i and save them to the output.tex file. If you want to read and save to the same file just use:

sed -i 's/#/'$i'/g' a.tex

You can read more about the 'sed' command here: Linux sed command

  • `'s/#/'$i'/g'` is leaving the contents of `$i` exposed to the shell for globbing and filename expansion so don't do that. Always quote your shell variables - `'s/#/'"$i"'/g'`. That has some caveats of course, see [is-it-possible-to-escape-regex-metacharacters-reliably-with-sed](https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed). – Ed Morton Nov 28 '22 at 10:32
  • 1
    But of course, `$i` will not be set to the latest matching line, it will be set to whatever it is in the calling shell (probably empty, or some random unrelated chaff) – tripleee Nov 28 '22 at 11:25