1

I have a plain text file with LaTeX commands like \hspace{5cm}. To convert this file to .odt some of my custom commands are not converted correctly. So I want to automatically find & replace specific commands but keep the content of the brackets (meaning that I want to keep most of the commands and just delete some). I know that I can just open gedit and do the replacing by hand, but this is for a script for repeated, automatic replacement.

I already searched for this, but so far only found answers to delete brackets while keeping there content (cf. here, here)). I also looked at some introductions to sed (e.g. here or here) without any success.

Example:

This is my \textbf{text} where there are about \prc{5} commands, i.e. \mErrRange{30}{20}{m}.

So, since these are a percentage and an error range, I want to delete the command & curly brackets and get something like this (keeping the \textbf{...} command):

This is my \textbf{text} where there are 5 % commands, i.e. 30 ± 20 m.

What I tried so far:

Various ways to usesed, like:

sed -i -e 's/\\prc{\(.*\)}/\1%/g' hello.txt

This already gives me:

This is my \textbf{text} where there are about 5} commands, i.e. \mErrRange{30}{20}{m%.

(Replacing the last curly bracket in the line, but leaving the other one in its place.)

So, now I have no clue how to continue with that. Maybe I should use another tool instead of sed?! I am happy about any suggestion running on Ubuntu & in the terminal without installing too much.

1

Here's a way:

sed 's/\\prc{\([^}]*\)}/\1 %/g'

This will capture everything inside the brackets following \prc and save it in group 1, you can use this to replace the command with the content of the brackets. [^}]* simply takes everything except the closing bracket here. g stands for “globally” and means it will substitute all occurences of the pattern in the line instead of just the first one – you'll want that for every expression in your case.

As for the other one, just use multiple groups:

sed 's/\\mErrRange{\([^}]*\)}{\([^}]*\)}{\([^}]*\)}/\1 ± \2 \3/g'

You can combine as many of those expressions as you like, but it gets easily unclear. I recommend writing a sed script with one expression per line like so:

#!/bin/sed -f
s/\\prc{\([^}]*\)}/\1 %/g
s/\\mErrRange{\([^}]*\)}{\([^}]*\)}{\([^}]*\)}/\1 ± \2 \3/g

Save it as e.g. script.sed, make it executable with chmod +x /path/to/script.sed and run it with /path/to/script.sed.

Example run

$ /path/to/script.sed <hello.txt
This is my \textbf{text} where there are about 5 % commands, i.e. 30 ± 20 m.

I let the shell open input files as often as possible, hence <hello.txt instead of just hello.txt (which also works!). If you're interested in what ups this exactly has I recommend this answer on unix.SE.

  • Thank you, this works great! I was searching for the [^}]* part. It is imho hard to find good documentation on sed. – bamphe Feb 5 '18 at 13:55
  • Oh, just saw that you forgot to escape the \prc & \mErrRange in the script part (but couldn't edit it since these are not > 6 char.) And thanks for the extra explanation on why to use <hello.txt here :) – bamphe Feb 5 '18 at 14:03
  • @bamphe You're totally right, I corrected it – thank you! As for regular expressions, I really like regular-expressions.info, sed uses POSIX BRE and what you searched for are POSIX Bracket Expressions. To try it out I often use regexr.com. – dessert Feb 5 '18 at 14:15
  • Nice! These are really helpful sites, thanks again :) – bamphe Feb 5 '18 at 14:26

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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