C Shell modulus operator - linux

I know c shell is very unfriendly but I am stuck with it. So can someone help me with this should-be-a-easy syntax error ? I would like to use modulus operator in c shell. So the command is like this and it keeps giving me syntax error of expr command.
set aVAr =`expr $number * 2 % $frequency`
I found out I can type "expr 6 % 5 " and "expr 3 * 2". However, I can not use command as "expr 3 * 2 % 5 ". What's wrong with it ? I think CSH should be table to take three operands at the same time ? Thank you very much,

expr is a command, not part of csh. You must escape the * to prevent csh from trying to expand it, as in
set aVAr =`expr $number \* 2 % $frequency`

Related

what is the difference between $(($RANDOM % 10 +1)) and $(( ( RANDOM % 10 ) + 1 ))

So I'm trying to create a random number limit the range from 1 to 10. There is a slightly different syntax between the two and I don't know if there any difference between those.
$(($RANDOM % 10 +1))
I tried this and it's working fine.
$(( ( RANDOM % 10 ) + 1 )). Including an extra () between RANDOM % 10 and +1 seems to work the same as the code above. But it has only one $ instead of 2.
Nothing. % has higher precedence (the same as *) than +, so the unparenthesized version is equivalent to the explicitly parenthesized one.
I originally missed that the second one also used RANDOM instead of $RANDOM. In an arithmetic context, a string is treated as an identifier, and is (recursively) expanded until you get an integer. If at any point the string is not a defined parameter, the value 0 is used instead. For example:
$ foo=bar
$ bar=6
$ echo $((bar))
6
$ echo $((foo))
6
In the last case, $foo expands to bar, which expands to 6.
IMO, it's better to use the explicit expansion. If the parameter isn't set due to a typo, you'll get an explicit error
$ foo=6
$ echo $((10 + $fo))
bash: 10 + : syntax error: operand expected (error token is "+ ")
rather than a silent "success" that might not be intended
$ echo $((10 + fo))
10 # ?? Why not 16?

What does the '${var// /+}' mean in shell script?

I have never seen the following shell script syntax:
cpu_now=($(head -n 1 /proc/stat))
cpu_sum="${cpu_now[#]:1}"
cpu_sum=$((${cpu_sum// /+}))
Can anyone explain what the ${cpu_sum// /+} mean here?
It means the same as $cpu_sum, but with all occurrences of  (a space) being replaced by +. (See ยง3.5.3 "Shell Parameter Expansion" in the Bash Reference Manual.)
cpu_sum=$((${cpu_sum// /+}))
It is actually 2 step operation:
First all the spaces are being replaced by + in ${cpu_sum// /+}
Then using $((...)) arithmetic addition is being performed for adding all the numbers in $cpu_sum variable to get you aggregate sum.
Example:
# sample value of cpu_sum
cpu_sum="3222 0 7526 168868219 1025 1 357 0 0 0"
# all spaced replaced by +
echo ${cpu_sum// /+}
3222+0+7526+168868219+1025+1+357+0+0+0
# summing up al the values and getting aggregate total
echo $((${cpu_sum// /+}))
168880350

How can I do division with variables in a Linux shell?

When I run commands in my shell as below, it returns an expr: non-integer argument error. Can someone please explain this to me?
$ x=20
$ y=5
$ expr x / y
expr: non-integer argument
Those variables are shell variables. To expand them as parameters to another program (ie expr), you need to use the $ prefix:
expr $x / $y
The reason it complained is because it thought you were trying to operate on alphabetic characters (ie non-integer)
If you are using the Bash shell, you can achieve the same result using expression syntax:
echo $((x / y))
Or:
z=$((x / y))
echo $z
I believe it was already mentioned in other threads:
calc(){ awk "BEGIN { print "$*" }"; }
then you can simply type :
calc 7.5/3.2
2.34375
In your case it will be:
x=20; y=3;
calc $x/$y
or if you prefer, add this as a separate script and make it available in $PATH so you will always have it in your local shell:
#!/bin/bash
calc(){ awk "BEGIN { print $* }"; }
Why not use let; I find it much easier.
Here's an example you may find useful:
start=`date +%s`
# ... do something that takes a while ...
sleep 71
end=`date +%s`
let deltatime=end-start
let hours=deltatime/3600
let minutes=(deltatime/60)%60
let seconds=deltatime%60
printf "Time spent: %d:%02d:%02d\n" $hours $minutes $seconds
Another simple example - calculate number of days since 1970:
let days=$(date +%s)/86400
Referencing Bash Variables Requires Parameter Expansion
The default shell on most Linux distributions is Bash. In Bash, variables must use a dollar sign prefix for parameter expansion. For example:
x=20
y=5
expr $x / $y
Of course, Bash also has arithmetic operators and a special arithmetic expansion syntax, so there's no need to invoke the expr binary as a separate process. You can let the shell do all the work like this:
x=20; y=5
echo $((x / y))
To get the numbers after decimal point, you can do this:-
read num1 num2
div=`echo $num1 / $num2 | bc -l`
echo $div
let's suppose
x=50
y=5
then
z=$((x/y))
this will work properly .
But if you want to use / operator in case statements than it can't resolve it.
In that case use simple strings like div or devide or something else.
See the code

ksh - var = $var + 1 returns 1+1 string

My code:
RETVAL1=-1
if [ $RETVAL1 -le 0 ] ; then
RETVAL1=$RETVAL1+1
print "RETVAL1: $RETVAL1"
fi
And it prints RETVAL1: -1+1
Any idea how to repair it please?
To perform arithmetic operation, use the let command: let RETVAL1=RETVAL1+1
Moreover, enclosing the expression between $(( and )) would also interpret it as an arithmetic operation. echo $((RETVAL+1))
Use the let command. This command performs arithmic operations. The + operator performs string addition.
Use it like this:
let RETVAL1=RETVAL1+1
You can also use the expr command for more general expressions.
One way:
((RETVAL1=RETVAL1+1))
Shell variables don't work like variables in most programming languages. If you want to add 1 to an integer stored in a variable, you'll need an arithmetic expression. I'm no ksh wizard, but the usual Bourne-derived-shell arithmetic expression syntax is:
RETVAL1=$((RETVAL1 + 1))
or
((RETVAL1 = RETVAL1 + 1))

csh inline math

I need to do some integer math in csh (and no, other shells are not an option, nor is bc, nor is perl, nor is python, period).
In bash my task would look like
seq 1 1 10 > m.txt #supplied from elsewhere
a=2 #supplied from elsewhere
b=3 #supplied from elsewhere
head -n $[$a*$b] m.txt # the line in question
then the question is Is there an expression in csh that computes $[$a*$b] inline?
I know that I can do # c = $a * $b in csh, but that's not inline. I did a little bit of googling and searching SO, but no success so far, so any help is greatly appreciated!
Are your use of square-brackets meant to indicate an array notation or matrix math? csh has no such built-in features.
ELSE, if you mean like bash $(($a * $b)), you can use csh cmd-substitution with backquotes to give you
head -n `expr $a \* $b` m.txt
Note that if your goal was to avoid spawning extra processes, this does not meet your goal, but it is "in-line"
Edit I see I mistyped as $( $a * $b ), see inline correction above.
IHTH.
Without using something outside of the shell, no.
The usual culprit for math from old school shell scripts is expr:
head -n `expr $a \* $b` m.txt
but if that's just as verboten as bc et al, then you're out of luck. Period.
Yes, but it's not pretty:
% seq 1 1 10 > m.txt
% set a = 2
% set b = 3
% head -n `# tmp = $a * $b ; echo $tmp ; unset tmp` m.txt
1
2
3
4
5
6
Note that this will clobber $tmp if you happen to have a variable of that name, so choose a unique name.
(Though I wonder why bc, perl, and python are not an option.)

Resources