Convert excel formula to linux bash script - excel

I'm trying to convert the following excel-formula into a simple bash script:
=IF(B3*10>B5,1,IF(TRUNC(B5/B3/10)>3,3,TRUNC(B5/B3/10)))
Examples:
If B3="2" and B5="39"; the output ("VAL") should be 1
If B3="2" and B5="40"; the output ("VAL") should be 2
If B3="2" and B5="60"; the output ("VAL") should be 3
This is what I've tried, but the output is not correct:
if (( $B3 \* 10 > $B5 )); then
if (( $B5 \/ $B3 \/ 10 > 3 )); then
VAL="3"
else
VAL=`expr $B5 \/ $B3 \/ 10`
fi fi
Where is the error? :)

The main problem is that you're not setting VAL to 1 in the first "true" branch.
if (( B3 * 10 > B5 )); then
VAL=1
elif (( B5 / B3 / 10 > 3 )); then
VAL=3
else
VAL=$((B5 / B3 / 10))
fi
bash lets you refer to variables without the $ inside an arithmetic expression.
Testing:
B3=2
for B5 in 10 39 40 60 80; do
if (( B3 * 10 > B5 )); then
branch="first"
VAL=1
elif (( B5 / B3 / 10 > 3 )); then
branch="second"
VAL=3
else
branch="third"
VAL=$((B5 / B3 / 10))
fi
echo "$B3 $B5 $VAL $branch"
done
2 10 1 first
2 39 1 third
2 40 2 third
2 60 3 third
2 80 3 second

Related

Combine all the columns of two files using bash

I have two files
A B C D E F
B D F A C E
D E F A B C
and
1 2 3 4 5 6
2 4 6 1 3 5
4 5 6 1 2 3
I want to have something like this:
A1 B2 C3 D4 E5 F6
B2 D4 F6 A1 C3 E5
D4 E5 F6 A1 B2 C3
I mean, combine both files pasting the content of all columns.
Thank you very much!
Here's a bash solution:
paste -d' ' file1 file2 \
| while read -a fields ; do
(( width=${#fields[#]}/2 ))
for ((i=0; i<width; ++i)) ; do
printf '%s%s ' "${fields[i]}" "${fields[ i + width ]}"
done
printf '\n'
done
paste outputs the files side by side.
read -a reads the columns into an array.
in the for loop, we iterate over the array and print the corresponding values.
Could you please try following, trying to do some fun with combinations of xargs + paste here.
xargs -n6 < <(paste -d'\0' <(xargs -n1 < Input_file1) <(xargs -n1 < Input_file2))

How to get next weekday number

In Debian 6 Linux shell script
#!/bin/sh
backupday=$(date +%u)
assings weekday number to backupday variable.
In my Linux
Monday returns 1
Thuesday returns 2
...
Saturady returns 6
Sunday returns 7
How to get next day weekday number:
Monday should return 2
Thuesday should return 3
...
Saturady should return 7
Sunday should return 1
I think you can use the FORMAT Interpreted sequences %w instead of %u.
It start with Saturday (%w day of week (0..6); 0 is Sunday).
And it's easy to plus 1 to get what your want.
$ echo $(($(date +%w --date=Saturday) + 1))
7
$ echo $(($(date +%w --date=Sunday) + 1))
1
$ echo $(($(date +%w --date=Monday) + 1))
2
This should do:
$ echo $(( $(date +%u --date=Saturday) % 7 + 1 ))
7
$ echo $(( $(date +%u --date=Sunday) % 7 + 1 ))
1
$ echo $(( $(date +%u --date=Monday) % 7 + 1 ))
2

display a - 1 - b - 2 - c - 3...- z - 26 by creating 2 process and each process run at once with a random sleep of 1 to 5

display a1b2c3...z26 by creating 2 process and each process run seperatley with a random sleep of 1 to 5
is there any way to show off
the process 1 has to wait for process 2 respectively
p1 will generate abcdef... with sleep $[ ( $RANDOM % 5 ) + 1 ]s
p2 will generate 12345..with sleep $[ ( $RANDOM % 5 ) + 1 ]s
Process 1 ./abc.sh
> cd /home/sanjaisambu/Sanjai/a1b2/ for j in {a..z} do
> while [ -f './syncfile' ]
> do
> echo 'process 1 waiting'
> sleep 1
> done
> touch ./syncfile
> echo -n $j >> a1b2.txt
> sleep $[ ( $RANDOM % 5 ) + 1 ]s done
Process 2 123.sh
> #!/bin/bash cd /home/sanjaisambu/Sanjai/a1b2/ for j in $(seq 1 26) do
> while [ ! -f './syncfile' ]
> do
> echo 'process 2 is waiting'
> sleep 1
> done
> echo -n - $j - >> a1b2.txt
> rm ./syncfile
> sleep $[ ( $RANDOM % 5 ) + 5 ]s done
When we Execute
./abc.sh & ./123.sh
Output:
a - 1 -b- 2 -c- 3 -d- 4 -e- 5 -f- 6 -g- 7 -h- 8 -i- 9 -j- 10 -k- 11
-l- 12 -m- 13 -n- 14 -o- 15 -p- 16 -q- 17 -r- 18 -s- 19 -t- 20 -u- 21 -v- 22 -w- 23 -x- 24 -y- 25 -z- 26

How do I generate random numbers in 3 lines - Linux Shell Script

I would like to write a code that can generate 3 rows of 6 random numbers spaced out, which shuffle after a given time (0.5 seconds), and no new rows are created, basically 6 random numbers keep generating in 3 rows.
The code I have so far is:
echo " "
echo " "
echo " "
for i in {1..5};
do
for i in {1..1};
do
echo -ne " $(($RANDOM % 100)) $(($RANDOM % 100)) $(($RANDOM % 100)) $(($RANDOM % 100)) $(($RANDOM % 100)) $(($RANDOM % 100))\r"
done
sleep 0.5
done
However, when I try to add the second and third row to this, it doesn't seem to work the way I want it. A sample output could look like:
45 88 85 90 44 22
90 56 34 55 32 45
58 99 42 10 48 98
and between these numbers, new ones will generate, keeping only 6 columns and 3 rows. I have tried making matrix too but it didn't work for me.
I don't know if you have it finish, but continuing on from the comment, I would fill an indexed array with random values between 1-100, e.g.
#!/bin/bash
for ((i = 0; i < 18; i++)); do ## fill array with random values
a[i]=$(($RANDOM % 100 + 1))
done
What you would then want is a function you could call, passing the number of values in each row (so you can output a '\n' after those digits print) and then the array values as arguments to the function to read into a local array within the function (of course, you can just use the original array without worrying about passing elements as arguments, but I prefer using local values within function to preserve values in other scopes unchanged. For that your print function could be something like:
## function to print array in shuffled order, using tput for cursor control
prnarray() {
local n=$1
local al=( ${#:2} )
local c=0
for i in $(shuf -i 0-$((${#al[#]} - 1))); do
[ "$c" -gt '0' -a $((c % n)) -eq '0' ] && printf "\n"
printf " %3d" "${al[i]}"
((c++))
done
printf "\n"
tput cuu 6 ## tput is used for cursor control to move back to top
}
Then you really don't need much else bu a loop to print the array, sleep for some period of time and then call prnarray again to overlay the output with a new shuffle. e.g.
tput sc ## save cursor position
## call prnarray 3 times with 5 sec. delay between displays
declare -i c=0
while (( c < 3 )); do
prnarray 3 ${a[#]}
((c++))
sleep 5
done
tput rc ## restore cursor position
Example Use/Output
The array will print in the same spot every 5 seconds with the same elements shuffled to different positions within the array.
$ sh randomshuf.sh
33 30 34
86 98 48
94 89 80
50 57 34
11 45 57
80 42 22
Give it a shot and let me know if you have any questions.
Note: to make it 3x6 change the lines:
tput cuu 3
and
prnarray 6 ${a[#]}
With those changed your output would resemble:
$ sh randomshuf.sh
85 9 45 14 18 16
6 59 43 19 29 58
7 89 18 72 29 29
I would recommend you to avoid using the shell for this. The shell is great for automating system administration tasks - e.g interact with files, directories, shell commands -, but it is also great to keep people away from learning a 'real' and most powerful programming language.
python, ruby or perl can help you out.
if all you have is a hammer, everything looks like a nail.
e.g ruby
def print_random_numbers(num)
random_numbers = []
num.times do |n|
random_numbers << rand(100)
end
puts random_numbers.join(' ')
puts
end
while true
3.times do
print_random_numbers(6)
end
sleep 0.5
end
I'm not sure whether I really understand your problem, but:
This gets you 6 numbers taken at random from the range 1-100
numbers=$(shuf -i 1-100 -n 6)
echo $numbers
The numbers are selected without repetition. If you want repetition, use -r.
This gives you a permutation of the numbers drawn before:
echo $numbers | tr ' ' '\n' | shuf | xargs echo

Can't add more than 2 variables [duplicate]

This question already has an answer here:
Sorting 3 columns and getting the average
(1 answer)
Closed 6 years ago.
I have a problem whenever I add more than 3 numbers with multiple operators. (I tried expr, bc,
SUM=$(( $S1 + $S2 + $S3 ))
and many other forms, but whenever I have 3 variables I get this error.
expr: non-integer argument
expr: syntax error
This is when I do it with 2 variables (works fine)
#!/bin/sh
FILE=$1
while read -r SID FIRST LAST S1 S2 S3
do
SUM=$(expr $S1 + $S2)
AVG=$(expr $SUM / 3)
printf '%d [%d] %s, %s\n' "$AVG" "$SID" "$LAST" "$FIRST"
done < "$FILE" | sort
and when I do 3 variables (doesn't work)
#!/bin/sh
FILE=$1
while read -r SID FIRST LAST S1 S2 S3
do
SUM=$(expr $S1 + $S2 + $S3)
AVG=$(expr $SUM / 3)
printf '%d [%d] %s, %s\n' "$AVG" "$SID" "$LAST" "$FIRST"
done < "$FILE" | sort
expr: non-integer argument
expr: syntax error
txt file
123456789 Lee Johnson 72 85 90
999999999 Jaime Smith 90 92 91
888111818 JC Forney 100 81 97
290010111 Terry Lee 100 99 100
199144454 Tracey Camp 77 84 84
299226663 Laney Camp 70 74 71
434401929 Skyler Camp 78 81 82
928441032 Jess Forester 85 80 82
928441032 Chris Forester 97 94 89
The shell absolutely supports this; thus, the problem is with your data. Try the following:
s1=1
s2=2
s3=3
echo $(( s1 + s2 + s3 ))
...run, and showing output 6, here.
Likewise:
s1=1
s2=2
s3=3
expr "$s1" + "$s2" + "$s3"
...run, and showing output 6, here.

Resources