Reputation: 7957
I have this Bash script and I had a problem in line 16. How can I take the previous result of line 15 and add it to the variable in line 16?
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in `ls output-$i-*`; do
echo "$j"
metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
num= $num + $metab (line16)
done
echo "$num"
done
Upvotes: 794
Views: 1373400
Reputation: 247102
In Bash,
num=5
x=6
(( num += x ))
echo $num # ==> 11
Note that Bash can only handle integer arithmetic, so if your AWK command returns a fraction, then you'll want to redesign: here's your code rewritten a bit to do all math in AWK.
num=0
for ((i=1; i<=2; i++)); do
for j in output-$i-*; do
echo "$j"
num=$(
awk -v n="$num" '
/EndBuffer/ {sum += $2}
END {print n + (sum/120)}
' "$j"
)
done
echo "$num"
done
Upvotes: 28
Reputation: 1
This is my solution
5.1
git clone https://github.com/datablist/sample-csv-files.git
5.2
cd sample-csv-files
git log --pretty=format:"%h - %s" -n 3
5.3
awk -F, 'NR>=40 && NR<=70 {print $1":"$2":"$3}' files/people/people-100.csv
5.4
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Utilizare: $0 adresa_de_email"
exit 1
fi
EMAIL=$1
FILE="files/people/people-10000.csv"
RESULT=$(grep -n "$EMAIL" "$FILE")
if [ -z "$RESULT" ]; then
echo "Adresa de email '$EMAIL' nu a fost găsită."
else
echo "Date găsite: $RESULT"
fi
1
Here is my solution:
5.1
mkdir -p ~/student/my-app
cd ~/student/my-app
git init
5.2
echo "Hello, World!" > ~/student/my-app/hello.txt
cd ~/student/my-app
git add hello.txt
git commit -m "Added hello.txt with 'Hello, World!'"
5.3
command -v cowsay >/dev/null 2>&1 || sudo apt-get install -y cowsay
5.4
echo "PID-ul procesului părinte este: $$" și "PPID-ul este: $(ps -p $$ -o ppid=)"
2
Upvotes: -1
Reputation: 1
This is my solution: 6.1 tail -n 15 ~/.bash_history | base64 | sha256sum
6.2
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Utilizare: $0 nume_utilizator"
exit 1
fi
USERNAME=$1
PASSWORD=$(openssl rand -base64 6 | tr -d 'A-Z+/=')
useradd -m $USERNAME
echo "$USERNAME:$PASSWORD" | chpasswd
echo "Utilizatorul '$USERNAME' a fost creat."
echo "Parola: $PASSWORD"
6.3
for i in {1..50}; do echo "This is mambo no. 5."; done > mambo_no_5.txt && openssl enc -aes-128-cbc -salt -in mambo_no_5.txt -out mambo_no_5.enc -k yourpassword 6.4 nano ~/.bashrc export HISTSIZE=50 source ~/.bashrc
1
Here is my solution: 6.1 #!/bin/bash
sum=0
count=0
while true; do
echo -n "Introduceți un număr (0 sau non-număr pentru a opri): "
read num
# Verificăm dacă inputul este un număr
if [[ $num =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then
if [ $num -eq 0 ]; then
break
fi
sum=$(echo "$sum + $num" | bc)
((count++))
else
break
fi
done
if [ $count -ne 0 ]; then
average=$(echo "scale=2; $sum / $count" | bc)
echo "Media aritmetică este: $average"
else
echo "Nu s-au introdus numere valide."
fi
6.2 #!/bin/bash
if [ $# -eq 0 ]; then
echo "Utilizare: $0 nume_utilizator"
exit 1
fi
username=$1
if getent passwd "$username" > /dev/null 2>&1; then
# Extragem UID-ul și shell-ul
uid=$(getent passwd "$username" | cut -d: -f3)
shell=$(getent passwd "$username" | cut -d: -f7)
echo "Utilizator: $username, UID: $uid, Shell: $shell"
else
echo "Eroare: Utilizatorul '$username' nu există."
fi
6.3
chmod +x nume_script.sh
sudo mv nume_script.sh /usr/local/bin
Sau cu alias
6.4
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Utilizare: $0 -u (utilizator curent) | -m (memorie liberă) | orice
altceva (eroare)"
exit 1
fi
case $1 in
-u)
echo "Utilizatorul curent este: $(whoami)"
;;
-m)
free -h | grep Mem | awk '{print "Memorie liberă: " $4}'
;;
*)
echo "Argument necunoscut. Utilizați -u pentru utilizatorul curent sau
-m pentru memoria liberă."
;;
esac
2
Upvotes: -2
Reputation: 7103
Works on MacOS. bc is a command line calculator
#!/bin/bash
sum=0
for (( i=1; i<=5; i++ )); do
sum=$(echo "$sum + 1.1" | bc) # bc: if you want to use decimal
done
echo "Total: $sum"
Upvotes: -1
Reputation:
#!/usr/bin/bash
#integer numbers
#===============#
num1=30
num2=5
echo $(( num1 + num2 ))
echo $(( num1-num2 ))
echo $(( num1*num2 ))
echo $(( num1/num2 ))
echo $(( num1%num2 ))
read -p "Enter first number : " a
read -p "Enter second number : " b
# we can store the result
result=$(( a+b ))
echo sum of $a \& $b is $result # \ is used to espace &
#decimal numbers
#bash only support integers so we have to delegate to a tool such as bc
#==============#
num2=3.4
num1=534.3
echo $num1+$num2 | bc
echo $num1-$num2 | bc
echo $num1*$num2 |bc
echo "scale=20;$num1/$num2" | bc
echo $num1%$num2 | bc
# we can store the result
#result=$( ( echo $num1+$num2 ) | bc )
result=$( echo $num1+$num2 | bc )
echo result is $result
##Bonus##
#Calling built in methods of bc
num=27
echo "scale=2;sqrt($num)" | bc -l # bc provides support for calculating square root
echo "scale=2;$num^3" | bc -l # calculate power
Upvotes: 6
Reputation: 263
Use the shell built-in let
. It is similar to (( expr ))
:
A=1
B=1
let "C = $A + $B"
echo $C # C == 2
Source: Bash let builtin command
Upvotes: 11
Reputation: 182
You should declare metab as integer and then use arithmetic evaluation
declare -i metab num
...
num+=metab
...
For more information, see 6.5 Shell Arithmetic.
Upvotes: 11
Reputation: 85855
Another portable POSIX compliant way to do in Bash, which can be defined as a function in .bashrc
for all the arithmetic operators of convenience.
addNumbers () {
local IFS='+'
printf "%s\n" "$(( $* ))"
}
and just call it in command-line as,
addNumbers 1 2 3 4 5 100
115
The idea is to use the Input-Field-Separator(IFS), a special variable in Bash used for word splitting after expansion and to split lines into words. The function changes the value locally to use word-splitting character as the sum operator +
.
Remember the IFS
is changed locally and does not take effect on the default IFS
behaviour outside the function scope. An excerpt from the man bash
page,
The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words on these characters. If IFS is unset, or its value is exactly , the default, then sequences of , , and at the beginning and end of the results of the previous expansions are ignored, and any sequence of IFS characters not at the beginning or end serves to delimit words.
The "$(( $* ))"
represents the list of arguments passed to be split by +
and later the sum value is output using the printf
function. The function can be extended to add scope for other arithmetic operations also.
Upvotes: 7
Reputation: 279
I always forget the syntax so I come to Google Search, but then I never find the one I'm familiar with :P. This is the cleanest to me and more true to what I'd expect in other languages.
i=0
((i++))
echo $i;
Upvotes: 27
Reputation: 209
I really like this method as well. There is less clutter:
count=$[count+1]
Upvotes: 20
Reputation: 26106
There are a thousand and one ways to do it. Here's one using dc
(a reverse Polish desk calculator which supports unlimited precision arithmetic):
dc <<<"$num1 $num2 + p"
But if that's too bash-y for you (or portability matters) you could say
echo $num1 $num2 + p | dc
But maybe you're one of those people who thinks RPN is icky and weird; don't worry! bc
is here for you:
bc <<< "$num1 + $num2"
echo $num1 + $num2 | bc
That said, there are some unrelated improvements you could be making to your script:
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in output-$i-* ; do # 'for' can glob directly, no need to ls
echo "$j"
# 'grep' can read files, no need to use 'cat'
metab=$(grep EndBuffer "$j" | awk '{sum+=$2} END { print sum/120}')
num=$(( $num + $metab ))
done
echo "$num"
done
As described in Bash FAQ 022, Bash does not natively support floating point numbers. If you need to sum floating point numbers the use of an external tool (like bc
or dc
) is required.
In this case the solution would be
num=$(dc <<<"$num $metab + p")
To add accumulate possibly-floating-point numbers into num
.
Upvotes: 37
Reputation: 23514
Use the $(( ))
arithmetic expansion.
num=$(( $num + $metab ))
See Chapter 13. Arithmetic Expansion for more information.
Upvotes: 183
Reputation: 96306
For integers:
Use arithmetic expansion: $((EXPR))
num=$((num1 + num2))
num=$(($num1 + $num2)) # Also works
num=$((num1 + 2 + 3)) # ...
num=$[num1+num2] # Old, deprecated arithmetic expression syntax
Using the external expr
utility. Note that this is only needed for really old systems.
num=`expr $num1 + $num2` # Whitespace for expr is important
For floating point:
Bash doesn't directly support this, but there are a couple of external tools you can use:
num=$(awk "BEGIN {print $num1+$num2; exit}")
num=$(python -c "print $num1+$num2")
num=$(perl -e "print $num1+$num2")
num=$(echo $num1 + $num2 | bc) # Whitespace for echo is important
You can also use scientific notation (for example, 2.5e+2
).
Common pitfalls:
When setting a variable, you cannot have whitespace on either side of =
, otherwise it will force the shell to interpret the first word as the name of the application to run (for example, num=
or num
)
num= 1
num =2
bc
and expr
expect each number and operator as a separate argument, so whitespace is important. They cannot process arguments like 3+
+4
.
num=`expr $num1+ $num2`
Upvotes: 1334
Reputation: 119
#!/bin/bash
num=0
metab=0
for ((i=1; i<=2; i++)); do
for j in `ls output-$i-*`; do
echo "$j"
metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
let num=num+metab (line 16)
done
echo "$num"
done
Upvotes: 4