I have several equations mixed throughout a document, appearing in the following forms:
5^4 %A
3^-1 %B
5.01 x 10^2.05 %C
5.01 x 10^2 %D
-5 x 10^3 %E
In other words, they fit in the format of x^y, or z * x^y, where z, x, and y can be any integer or rational number (expressed with a decimal point), positive or negative.
I wish to convert these to math mode for TeX. E.g.:
$5.01 \cdot 10^2$
With much assistance from others, I have managed to create this BASH script with sed to solve items A and B:
sed "s/\-\{0,1\}[0-9]\{1,\}^\-\{0,1\}[0-9]\{1,\}/$&$/" input > output
This is able to convert items A and B to math mode, but I found it only converts the first occurrence it finds within a line. For instance, if a line says 5^10 is greater than 1^2 it converts this to $5^10$ is greater than 1^2. A second pass with the script results in $$5^10$$ is greater than 1^2.
I managed to modify the above script to handle items C, D, and E, but cannot figure out how to handle the back second part (I have marked it with "???"):
sed "s/\-\{0,1\}[0-9]\{1,\}\ x\ \-\{0,1\}[0-9]\{1,\}^\-\{0,1\}[0-9]\{1,\}/???/" input > output
This presents a problem:
Even if the above could work, if I first run the first sed script, then run the second, the first confuses the second, i.e. I would end up with 5.01 x $10^2.05$. If I ran the second script first, I would end up with $5.01 x $10^2.05$$ after running the second script.
In short, how can I perform this kind of conversion for all items within a document?
5^4 --> $5^4$
3^-1 --> $3^-1$
5.01 x 10^2.05 --> $5.01 \cdot 10^2.05$
5.01 x 10^2 --> $5.01 \cdot 10^2$
-5 x 10^3 --> $-5 \cdot 10^3$
but I found it only converts the first occurrence it finds within a line
Use the /g global replacement flag.
Converting your text is best done in several passes
Pass 1
sed 's/\(-\?[0-9].\?[0-9]*\) x \(-\?[0-9]\{1,\}\)^\([0-9]\{1,\}\.\?[0-9]*\)/$\1 cdot \2^^\3$/g' input > tmp
What we've done here is capture \(...\) x \(...\)^\(...\) into the sed remembered patterns \1 \2 and \3 which we then use to convert the text.
This deals with your %C,%D,%E and for example converts 5.01 x 10^2.05 into $5.01 cdot 10^^2.05$. Note that we have converted the occurrences of ^ into ^^ temporarily.
Pass 2
sed -i 's/-\?[0-9]\+\^-\?[0-9]\+/$&$/g' tmp
This deals with your examples %A and %B. As we previously converted the ^ in 10^2.05 to ^^ this was ignored by pass 2 solving the problems you noted.
Pass 3
sed -i 's/\^^/^/g' tmp
Which simply converts the ^^ back into ^
Based on the output you need, will this following method work for you?
[jaypal~/Temp]$ cat file0
5^4
3^-1
5.01 x 10^2.05
5.01 x 10^2
-5 x 10^3
[jaypal~/Temp]$ sed -e 's/^/\$/' -e 's/$/\$/' -e 's/x/\\cdot/' file0
$5^4$
$3^-1$
$5.01 \cdot 10^2.05$
$5.01 \cdot 10^2$
$-5 \cdot 10^3$
This might work for you:
sed -i 's/\(-\?[0-9]\+\(\.[0-9]\+\)\? \)x\( -\?[0-9]\+\^-\?[0-9]\+\(\.[0-9]\+\)\?\)\|\(-\?[0-9]\+\^-\?[0-9]\+\)/$\1\\cdot\3\5$/g;s/\$\\cdot/$/g' file
although the GNU sed -r switch makes it look a lot less cluttered:
sed -ri 's/(-?[0-9]+(\.[0-9]+)? )x( -?[0-9]+\^-?[0-9]+(\.[0-9]+)?)|(-?[0-9]+\^-?[0-9]+)/$\1\\cdot\3\5$/g;s/\$\\cdot/$/g' file
Related
This question already has answers here:
How to print lines between two patterns, inclusive or exclusive (in sed, AWK or Perl)?
(9 answers)
Closed 4 years ago.
Suppose a file with such content:
a
x
y
z
c
some to be omitted
a
b
c
I want to print all those lines which are between the "a" line and "c" line (both with and without the "c" line are ok):
a
x
y
z
c
a
b
c
I tried the sed command:
sed -n '/a/{:my_tag /./p; N; /c/ t end; t my_tag; :end}'
and it gives me the output:
a
a
Does the N in the command work for once only? I cannot see any loop work out here.
the help info of sed is a little bit confusing and it seemed like I was doing in the wrong way.
Or maybe some tools rather than sed would be more helpful and efficient to this problem and please show me how.
Could you please try following(if ok with awk).
awk '/^a/{flag=1} flag; /^c/{flag=""}' Input_file
Output will be as follows.
a
x
y
z
c
a
b
c
With sed:
sed -n '/^a$/,/^c$/p' file
or
sed '/^a$/,/^c$/!d' file
Output:
a
x
y
z
c
a
b
c
I have a huge text file that has several iterations of the same thing at different times, with a basic structure of:
Header (5 lines)
Data (thousands of lines)
Header (5 lines)
Data (thousands of lines)
Header (5 lines)
Data (thousands of lines)
This repeats and goes on for a while.
I want to cull this file, by removing every other set of Header + Data. I was thinking I'd use sed, but I can't figure out how.
It might be of help that each "cycle" starts with the same line (for the purpose of this example, imagine it says Program X output) and that exact line only appears once, at the beginning of each "cycle".
Thanks
Keep track of how often you see the keywords, and print only when this count is an odd number:
awk '/Program X output/ {n++} n%2 == 1' <<END
Program X output
a
b
c
Program X output
d
e
Program X output
f
g
h
i
j
Program X output
m
n
o
END
Program X output
a
b
c
Program X output
f
g
h
i
j
Sounds like all you need is:
awk '/Program X output/ && c++{exit} 1' file
e.g.
$ seq 50 | awk '/2/ && c++{exit} 1'
1
2
3
4
5
6
7
8
9
10
11
If that's not all you need then edit your question to clarify your requirements and show us concise, testable sample input and expected output.
This might work for you (GNU sed):
sed -r '/Program X output/{x;s/^/x/;x};G;/\n(x{2})*$/!P;d' file
When encountering a header line, add 1 to a counter in the hold space (HS). Append the HS to every line and only print the first line in the pattern space (PS) if the counter is a multiple of the required amount.
I whant to replace a variable by some numbers and X's or even a direct equation like 3X+2 = 5
Yeah I'm codding a resolution of equations :D (i'm borred)
This is what i've written right now
Prompt E
Prompt F
while T [not equal to] 1
X+0.01 -> X
If E=F
1 -> T
If E=F
Disp X
End
So what i'm trying to do is say E is 3X+2 and F is 5
I test all the possible solutions by replacing X by every number and when it equals to F (so 5) i stop and print X
It works when I replace directly in the code the E and F but it's long and useless if I whant to use it.
If 3X+2=5
1 -> T
If 3X+2=5
Disp X
End
This works !!
So is it possible for the calculator to interpret that i'm saying that E is a long sentence ?
Thanks so much !
Ps : Don't worry if i make mistakes in my orthograph, (i'm french)
Ps 2 : Don't just tell me how to do a resolution of equation (Don't tell me what I can't do !! (lost (4 8 15 16 23 42)))
Are you asking how to input "3X+2" into the variable E?
In this case, you wouldn't want to use a variable, because variables in TI-84 can only be numbers. You would use strings, which store text instead of numbers. Go to VARS > String... to see the list of strings available.
Now, to find the numerical value of strings, you would use the expr( command. For example, expr("3X+2") where X=1 would return 5. You can find the expr( command in the catalog (2ND + 0).
You're looking for equation variables.
An expression can be stored into an equation variable such as Y₁; it will be evaluated every time it is encountered.
"3X+2→Y₁
5→X
Disp Y₁
-2→X
Disp Y₁
The above will print
17
-4
Equation variables are easier to use than strings, because they are automatically evaluated. There's no need to use expr(. To find the equation variables, press VARS > ENTER.
I have a data file which has the following arrangement :
#REY2_0 REY1_0 alpha1 alpha2 omega
1000 10000 (-3,0) (1,0) (-0.21259151,-0.17763971)
I have to use the REY2_0, REY1_0 and the second element of omega i.e -0.17763971 in this case. How would I be able to use this in splot ? Can I add multiple separators to gnuplot and then use the resulting columns ? How is this done ? Can I change the data file using sed?
Edit :
The sample output would be :
#REY2_0 REY1_0 alpha1 alpha2 omega
1000 10000 -3 0 1 0 -0.21259151 -0.17763971
You can use this sed,
sed 's/[(,)]/\t/g' yourfile
If you want to made the changes in file,
sed -i.bak 's/[(,)]/\t/g' yourfile
To get proper formatted output,
sed 's/[(,)]/\t/g' yourfile | column -t > newupdatedfile
It is working for your sample input file.
math 5/2 returns 2.
I want 2.5 -- how do I get decimal values?
You can "force" math to return fractions by default -- use the -l option to bc:
$ math 5/2
2
$ function bc
command bc -l $argv
end
$ math 5/2
2.50000000000000000000
Add this to one of your config.fish files
set -x BC_ENV_ARGS ~/.bc.cfg
Then create a .bc.cfg file to tell it out many decimal places to display
echo "scale = 5" >> .bc.cfg
This will:
math 5/2
2.50000
you have to force floating point division instead of integer division
math 5/2.0