1

I have recently wrote a script that will parse a whole bunch of files and increment the version number throughout. The script works fine for all files except one. It uses the following sed command (which was pieced together from various google searches and very limited sed knowledge) to find a line in a .tex file and increment the version number.

sed -i -r 's/(.*)(VERSION\}\{0.)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' fileName.tex

The issue with the above (which I am unsure how to fix) is that the line it finds to change appears as

\newcommand{\VERSION}{0.123},

and the sed command replaces the "\n" in the line above with the newline character, and thus outputting

ewcommand{\VERSION}{0.124} (with a newline before it).

The desired output would be:

\newcommand{\VERSION}{0.124}

How can I fix this?

d0sag3
  • 13
  • 3
  • 1
    Do not use `sed` for that. Use `awk`. – KamilCuk Apr 10 '20 at 14:54
  • The backslashes are treated differently all the time, look at the output with `echo \1\2$((\3+1))\4`, without quotes, the `\n` is stopped being parsed as a newline, but the ``\`` before `V` is now removed. See above comment. – Wiktor Stribiżew Apr 10 '20 at 14:59
  • Do you want to increment 0.123 by 0.001 or 123 by 1? – Cyrus Apr 10 '20 at 15:17
  • @Cyrus See the desired output. Both would actually work I suppose. – d0sag3 Apr 10 '20 at 15:37
  • @WiktorStribiżew Removing the quotations in the echo commands removes all the backsashes in the output. I'll look into ```awk```, never used that before. – d0sag3 Apr 10 '20 at 15:38
  • If you are looking for how to controlledly replace a literal string `\n` with a newline, see https://stackoverflow.com/questions/19762365/sed-help-matching-and-replacing-a-literal-n-not-the-newline – tripleee Aug 29 '21 at 06:51

2 Answers2

0

Alright so I was not able to get the answer from Cyrus to work because the file was finding about 50 other lines in my tex files it wanted to modify and I wasn't quite sure how to fix the awk statement to find just the specific line I wanted. However, I got it working with the original sed method by making a simple change.

My sed command becames two, where the first creates a temporary string %TMPSTR%, immediately followed by replacing said temp string to get the desired output and avoid any newline characters appearing.

sed -i -r 's/(.*)(VERSION\}\{0.)([0-9]+)(.*)/echo "\\%TMPSTR%{\\\2$((\3+1))\4"/ge' fileName.tex
sed -i -r 's/%TMPSTR%/newcommand/g' fileName.tex

So the line in the file goes from

\newcommand{\VERSION}{0.123} --> \%TMPSTR%{\VERSION}{0.124} --> \newcommand{\VERSION}{0.124}

and ends at the desired outcome. A bit ugly I suppose but it does what I need!

d0sag3
  • 13
  • 3
0

Use awk, that won't get confused by data with special characters. Your problem could be solved by temporarily replacing the backslashes, but I hope this answer will lead you to awk.

For one line:

echo '\newcommand{\VERSION}{0.123},' | tr '\' '\r' | 
   sed -r 's/(.*)(VERSION\}\{0.)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' | tr '\r' '\'

For a file

tr '\' '\r' < fileName.tex | 
   sed -r 's/(.*)(VERSION\}\{0.)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge' |
   tr '\r' '\' > fileName.tex.tmp && mv fileName.tex.tmp fileName.tex

When \n is the only problem, you can try

sed -i -r 's/\\n/\r/g;s/(.*)(VERSION\}\{0.)([0-9]+)(.*)/echo "\1\2$((\3+1))\4"/ge;s/\r/\\n/' fileName.tex
Walter A
  • 19,067
  • 2
  • 23
  • 43