Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'd like some advice on changing the formatting of some data in a file.

I have a large amount of data in a file. This is a output from a large Fortran program, it is formatted for a latex table. I wish to change the formatting but can not rerun the Fortran program with alternative formatting for the output. I've been playing with sed but not got very far.

A single line from a table is currently in the format

0.1 & 0.166685D+01 & 0.162768D+01 & 0.139468D+01 & 0.126904D+01 & 0.133247D+01 \\

I wish to change it to

0.1 & $0.16668510^{01}$ & $0.16276810^{01}$ & $0.13946810^{01}$ & $0.12690410^{01}$ & $0.133247 10^{01}$ \\

I currently have


sed -i 's/D\+./ 10^{/g' $1

which gets me as far as

0.1 & 0.166685 10^{01 & 0.162768 10^{01 & 0.139468 10^{01 & 0.126904 10^{01 & 0.133247 10^{01 \\

but I still need to add the closing brace and wrap each number in a pair of `$' symbols.

In an ideal word I would also change the data to 3 d.p as well but this is less important.

Any sed / regex masters able to help, or maybe a suggestion of another tool which may be better suited to this problem.



I've just realised in the example all of the powers are +01 in this line, this is chance, they can be anything and vary though the file, positive and negative. Another example line with some NaNs thrown in.

0.3 & 0.634620D-02 & NaN & NaN & -0.312678D-02 & 0.192654D-03 \\
share|improve this question
up vote 0 down vote accepted

And here is your sed expression:

sed -e 's/D+\([^ ]*\)/10^{\1}/g' -e 's/ \([^ &]*\) / $\1$ /g' -e 's/^/$/'

which reads as

s/D+\([^ ]*\)/10^{\1}/g

... substitute all occurrences of D+[word with no spaces] by 10^{[word with no spaces]}

s/ \([^ &]*\) / $\1$ /g

... substitute all occurrences of [space][word containing no spaces and &-chars][space] by [space]$[word containing no spaces and &-chars]$[space]


... and prefix the line with a $-sign (which was not catched by the expression above)

share|improve this answer

Here's a Perl one-liner that does the substitutions in 2 steps...

perl -pe ' s/D\+01/10\^{01}\$/g; s/\& /\& \$/g; ' < in.txt > out.txt


Okay, based on your changed requirements...

perl -pe ' 

s/ \& NaN//g;               # removes <space>&<space>NaN sequences
s/D\+/10\+/g;               # replace D+ with 10+
s/D\-/10\-/g;               # replace D- with 10- 
s/\+/\^{/g;                 # replace +  with ^{ 
s/(?<! )\-/\^{-/g;          # replace -  with ^{- if preceding char is not a <space> 
s/(?<!\.[0-9]) \&/\} \&/g;  # replace <space>& with }<space>& if preceding chars are not .<single-digit> seq. 
s/ \\/\} \\/g;              # replace <space>\ with }<space>\

' < in.txt > out.txt

At this point and beyond, you should probably write a proper script, but this works with the sample data that you provided. You can copy & paste it into bash as is.

share|improve this answer
Thanks. Is it possible ot alter it when the power of the exponent can be anything? I've only just noticed on the example I gave it's all +01 most of the time it varies, both positive an negative. – Tommy Jun 17 '11 at 21:36
Thanks I like this and have been playing with altering it trying to put it into a perl script but due to my zero knowledge of perl have had difficulty with a few minor things. I will give it another go some time but fell back onto sed solon as it's what I know. – Tommy Jun 18 '11 at 14:51
The perl -pe ' ' construct is for running a Perl script from the command line as a one-liner. The above takes in.txt as input, processes it, and then outputs the result as out.txt. You may need to fix the paths, or run it in the in.txt directory. For info on using Perl as an awk/sed/grep/etc. replacement, see the book Minimal Perl by Tim Maher. – Joe Internet Jun 19 '11 at 1:13

Piece of cake. When will I have projects with ancient programs that produce latex? :(

$ cat tmp/latex-table 
echo '0.1 & 0.166685D+01 & 0.162768D+01 & 0.139468D+01 & 0.126904D-21 & 0.133247D+01 \\' |\
sed -e 's/&\([^0-9]*\)\([0-9\.]*\)D\([+\-]\)\([0-9]*\)/\&\1$\2 10^{0\3\4}$/g'
raptor: ~
$ bash tmp/latex-table 
0.1 & $0.166685 10^{0+01}$ & $0.162768 10^{0+01}$ & $0.139468 10^{0+01}$ & $0.126904 10^{0-21}$ & $0.133247 10^{0+01}$ \\
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .