Bash arithmetic awk calculation fails [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 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)

Related

Search pattern in a specific line in bash [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I would like to find pattern in a specific line (no case sensitive). And if I find it make something.
I can’t use grep since find in all file.
What is the best method?
Try this, where 2 is the line that you want to search for pattern:
sed '2!d;/pattern/I!d' input
This sed script basically deletes all lines except line 2, as 2! is not line 2; then among all lines that get past that action, which means only line 2 in this case, all those not matching pattern are deleted too.
So all that remains, and is printed by sed implicitly, is line 2 only if it matches pattern.
Note that the flag I for case insensitivity is not POSIX, IIRC. Try it out. If it doesn't work, you can always use [pP][aA][tT][tT][eE][rR][nN].
Also note that this command will return 0 in both the case of matching and not matching. If you need to take action depending on whether the file matched or not, you can do like this
[[ -n $(sed '2!d;/pattern/I!d' input) ]] && echo matched || echo not matched
If the pattern is a variable, then you can include it like this:
sed '2!d;/'"$variable"'/I!d' input

bc calculation with large float 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 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

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.

Resources