bc calculation with large float number [closed] - bash

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have a large number and I want to make bc calculation.
Example:
T_Mab = 6.00899e+09
and I wanna print it like this:
echo 'T_Mab = '${T_Mab}' [s] = '${T_Mab}/31557600' [year]' | bc -l
It is giving me "syntax error". So how can I do it?

You cannot just write whatever you want to display and dump them to bc. Another issue is that bc does not accept scientific notations. Check [How to get bc to handle numbers in scientific (aka exponential) notation? for details.
Assuming that the number is already converted to the correct form as in the answers in the linked question, you can write it like this in bash.
T_Mab=6008990000
echo "${T_Mab} [s] = $(bc -l <<< ${T_Mab}/31557600) [year]"
Here-strings are added since bash 3.0, if you are using older version, just use $(echo ${T_Mab}/31557600|bc -l).
With all these said, you really should consider bc alternatives as suggested in the second answer of the linked question if you don't need arbitrary precision.

The syntax error is because bc doesn't read "e" notation, and can be reproduced with a greatly simplified example:
$ bc -l <<<"6.00899e+09"
(standard_in) 1: syntax error
We'll need to change to a syntax it does understand; we can do that in Bash:
v=6.00899e+09
v=${v/e/*10^} # 6.00899*10^+09
v=${v/^+/^} # 6.00899*10^09
bc -l <<<"($v)"
6008990000.00000
Or simply launder through a tool that does understand the notation:
printf '%f\n' "$v" | bc -l

Related

Bash arithmetic awk calculation fails [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
The community is reviewing whether to reopen this question as of yesterday.
Improve this question
The code snippet below extracts values from an xml file and store totals for days 1 to 7 and a grand total for the last 7 days - $lsd. The day figures are 6 digit numbers with 3 decimal places. I cannot make the 'awk' function work. Everything I have tried produces either "0.000" or "". Changing the INC operator to simple addition gives similar results
Needless to say, I'm a complete newbie to Bash Arithmetic. Please can somebody tell me where I'm going wrong.
for i in {1..7} ;
do
day=$(grep -oPm1 "(?<=<d00$i>)[^<]+" < data.xml)
printf "%.3f" $day > day$i.txt ;
awk 'BEGIN{lsd += $day}'
done ;
printf "%.3f" $lsd > lsd1.txt
Please can somebody tell me where I'm going wrong.
(...)
awk 'BEGIN{lsd += $day}'
(...)
printf "%.3f" $lsd > lsd1.txt
does suggests that you are promptly ignoring that awk's variables and bash's variables are separate from each other, consider following example
x=10
awk 'BEGIN{x+=1;print x}' emptyfile
echo $x
does output
1
10
Observe that inside awk command x is unset, thus when increment by 1 is request it is assumed to be 0 thus print x does give 1 and awk did not anything to bash's x as shown by line with echo.
(tested in GNU Awk 5.0.1)

Bash scripting and linuxbash [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I hope someone can help me. my question is with a script in bash that receives a certain amount of parameters and then show them in the reverse order of the one. as I keep name one for each line in the vvariable and then show them around.
#!/bin/bash
var=""
for i in "$#";do
var+=`echo $i`
done
If you want reversed order, you have to loop in reversed order:
for ((i=$#; i>=1;i--)); do
a=${!i}
echo "$a"
done
The simplest way to achieve this would be:
echo $# | rev
$# stores all the arguments passed, and rev, as its name suggests, reverses the order of characters in the line.
Edit:
After reading your comment, I can suggest the following approach:
for i in `echo $# | rev`; do
j=`echo $i | rev`
echo -n "$j "
done

Take and use input as number [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
grep -o '\w\{4\}' file
I want to find the words longer than a value given by the user. Now, the above code gives me the words with at least 4 letters but if I'm replacing 4 with $n after i read a number into n it says that the content between my brackets is incorrect. How could I use a value read instead of a predefined one?
With single quotes, the $n will not be interpreted. It works if you use double quotes:
grep -o "\w\{$n\}" file
But I think you will want to use
grep -o "\w\{$n,\}" file
because else words of length 8-11 will match twice, 12-15 three times etc.
n=5
eval "grep -o '\w\{$n\}' filename"

Bash: trying to echo a string if there isn't enough memory left on the server [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I would like my script to echo a string, in case there isn't enough memory left on the server. I have tried many things, but the script does not work, I'm afraid its because of converting a string into a number ?
Here is what I have got:
freem=`free -m | sed -n '3p' | tail -c6 | xargs`
max_memory=1000
if [ freem -lt max_memory ]
then echo 'not enough'
else echo 'yay'
fi
freem does have the correct value, but the if does not work, it says:
check_memory.sh: 3: [: Illegal number: freem
I have tried many things, but I cannot get it to work :(.
Could someone please help me ?
Thank you
The answer of fedorqui already shows what you missed (the $'s for the variable names). I'd use something like:
let freem=$(free -m | awk '/cache:/ {print $NF}')
let max_memory=1000
if [ $freem -lt $max_memory ]
then echo 'not enough'
else echo 'yay'
fi
I prefer using $( ) instead of back ticks for readability. By using let you state that arg is an arithmetic expression, which makes more sense when comparing values.

How to read only number from a specific line in file using shell script? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
i want to write a shell script to read only number from each line in a file and store it in variable. file from which i must read is like this
file1.txt
Current Offset from Master : 939
Current Offset from Master : 27256
You can grep the numbers, and then loop through them and do whatever you want
cat file1.txt | grep -o '[0-9]*'
or simply
grep -o '[0-9]*' file1.txt
so your shell script could look like
for x in `grep -o '[0-9]*' file1.txt`;
do
# do something with $x
done
This should works:
for line in $(cat file.txt)
do
offset="${line//[^0-9]/}"
done

Resources