I'm new in shell scripting and am looking to like this output
1 | 1 | odd | Monday
1 | 2 | even |Tuesday
"
"
1 | 7 | odd | Sunday
2 | 1 | odd | Monday
2 | 2 | even| Tuesday
"
"
2 | 7 | odd | Sunday
3 | 1 | odd | Monday
3 | 2 | even| Tuesday
"
"
3 | 7 | odd | Sunday
I tried below script
i=1
j=1
while [ $i -le 3 ]
do
for (( j=1; j<=7; j++ ))
do
if [ $(($j%2)) -eq 0 ];
then
echo "$i | $j | even "
else
echo "$i | $j | odd"
fi
done
((i++))
done
am getting like this Output
1 | 1 | odd
1 | 2 | even
"
"
1 | 7 | odd
2 | 1 | odd
2 | 2 | even
"
"
2 | 7 | odd
3 | 1 | odd
3 | 2 | even
"
"
3 | 7 | odd
Please help me "Week Day Name incremental in fourth column" where can i add the week name.
date utility can display day of week, so you just need to tell her right date. Here is solution which does it with offset relatively to the actual date.
dow=`date +%u`
i=1
j=1
while [ $i -le 3 ]
do
for (( j=1; j<=7; j++ ))
do
offset=$(( $j - $dow ))
dow_str=`date --date="$offset days" +%A`
if [ $(($j%2)) -eq 0 ];
then
echo "$i | $j | even | $dow_str"
else
echo "$i | $j | odd | $dow_str"
fi
done
((i++))
done
You can also do it using array. Store all the days in an array as:
declare -a week=('Sunday' 'Monday' 'Tuesday' 'Wednesday' 'Thursday' 'Friday' 'Saturday');
and then to access it, do it in for loop with the key as j mod 7. This will give you the week day name starting from Monday.
Related
I have a bash script which outputs some statistics on the screen for each sample number(example shown below) when I run the test.sh code.
What I am trying to do is that to store the output in a variable and extract the Mean value for a testNum --> 11 and 52
A=`./test.sh` # I have all the output in a variable A
Now I need to extract the mean value of 11 which is -128 and -96 for 52
I'm trying and thinking How I can do this
Can anyone help me in this please ?
This is the example test code : test.sh
#!/bin/sh
echo Valid Numbers per States:3G phones
echo testNum N_States Mean Value
echo 1 10 -128
echo 2 10 -95
echo 3 10 -94
echo 4 10 -94
echo 5 10 -94
echo 6 10 -128
echo 7 10 -91
echo 8 10 -94
echo 9 10 -94
echo 10 10 -94
echo 11 10 -128
echo --------------------------------------------
echo Valid Numbers per States :4G phones
echo testNum N_States Mean Value
echo 36 10 -95
echo 40 10 -95
echo 44 10 -95
echo 48 10 -95
echo 52 10 -96
echo 56 10 -95
echo 60 10 -96
echo 64 10 -96
echo 100 10 -99
echo 104 10 -97
echo 108 10 -98
echo 112 9 -98
echo 116 9 -98
echo 120 9 -99
echo 124 9 -98
echo 128 9 -98
echo 132 9 -98
echo 136 9 -99
echo 140 9 -99
echo 144 9 -99
echo 149 9 -98
echo 153 9 -99
echo 157 9 -99
echo 161 9 -99
echo 165 9 -98
echo --------------------------------------------
I have used the commands echo "$x" | grep -w '^52' | cut -d' ' -f3
But Linux on my proprietary hardware doesn't allow ^ (not sure if its version or something) .. I can run this on any bash shell..works fine, but if I run the same command, it doesn't output anything.
So I started doing some awk on it
Here temp is 128
NF_Est is output of the script
echo "$NF_Est" | grep -w 128 | awk '{if ($1==128)print $0}' | tr -s " " | cut -d" " -f3
But this is not working if I am the "temp" values in multiple columns
Any suggestions where I am messing up (or) this can be done in a much simpler way?
You really want awk for this:
$ ./test.sh | awk '$1==11{print $3}'
-128
$ ./test.sh | awk '$1==52{print $3}'
-96
If you want to extract the value from $A instead of running the script, just do: echo "$A" | awk ...
You can use grep and cut to extract the information:
echo "$x" | grep -w '^11' | cut -d' ' -f3
echo "$x" | grep -w '^52' | cut -d' ' -f3
grep filters its input, outputting only lines that match the given pattern. ^ matches at the beginning of line. -w means "match whole words", without it, it would also output the lines 112 and 116.
cut extracts columns from its intput. -d specifies the delimiter, a space in this case, and -f says which columns to extract.
When adding numbers in a matrix, I get this error:
line 271: 1 2 3 4: syntax error in expression (error token is "2 3 4")
My add function:
add()
{
#Reading matrices into temp files
while read line1 <&3 && read line2 <&4
do
echo "$line1" | tr "\n" "\t" >> "temp50"
echo "$line2" | tr "\n" "\t" >> "temp60"
done 3<$temp1 4<$fileTwo
echo >>"temp50"
echo >>"temp60"
cat "temp60" >> "temp50"
i=1
x=1
while [ $i -le $totalNum ]
do
sum=0
cut -f $i "temp50" > "temp55"
while read num
do
sum=$(($sum + $num))
done <"temp55"
echo "$sum" | tr "\n" "\t" >> "temp65"
#try and remove hanging tab
if [[ "$x" -eq "$numcolOne" ]]
then
rev "temp65" > "temp222"
cat "temp222" | cut -c 1- >"temp333"
rev "temp333">"temp65"
x=0
fi
i=$((i+1))
x=$((x+1))
done
Matrix array (temp1):
1 2 3 4
5 6 7 8
Function is supposed to add the matrix array in the temp1 file; sample output:
2 4 6 8
10 12 14 16
Appreciate anyone's help!
I have a file with this format:
User_ID , Place_ID , Rating
U32 , 1305 , 2
U32 , 1276 , 2
U32 , 1789 , 3
U65 , 1985 , 1
U65 , 1305 , 1
U65 , 1276 , 2
I would like to iterate through this file, sort by Place_ID, iterate through repeated values in Place_ID and add the ratings, once the last element of the Place_ID is added, check if value > x and if true, push the Place_ID into an array.
Ex: Place_ID 1305: 2 + 1 / 2 = 1.5 > 1 ----> ids+=($id)
Place_ID 1276: 2 + 2 / 2 = 2 > 1 -----> ids+=($id)
I have tried with
test5 () {
id=0
count=0
rating=0
ids=()
ratings=()
for i in `sort -t',' -k 2 ratings.csv`
do
aux=`echo "$i"| cut -f2 -d','`
if (( $id != $aux )); then
if (( $rating != 0 )); then
rating=`echo "scale=1; $rating / $count" | bc -l`
if (( $(echo "$rating >= 1" | bc -l) )); then
ids+=($id)
ratings+=($rating)
fi
fi
id=$aux
count=0
rating=0
else
rating=$(($rating + `echo "$i"| cut -f3 -d','`))
count=$(($count + 1))
fi
done
echo ${#ids[#]}
echo ${#ratings[#]}
}
EDIT: I think it works, but is there a way to make it better? Something that doesn't force me to use as many if's and count.
Thanks for the help.
This is another option using less if's:
#!/bin/bash
sum=()
count=()
while read -r line; do
place=$(echo "$line" | cut -d',' -f2)
rating=$(echo "$line" | cut -d',' -f3)
sum[$place]=$(echo "$rating + ${sum[$place]-0}" | bc -l)
count[$place]=$((count[$place] + 1))
done < <( sed 1d ratings.csv | sort -t',' -k 2 | tr -d '[:blank:]' )
ratings=()
for place in "${!sum[#]}"; do
ratings[$place]=$(echo "scale=1; ${sum[$place]} / ${count[$place]}" | bc -l)
done
# ratings at this point has the ratings for each place
echo ${!ratings[#]} # place ids
echo ${ratings[#]} # ratings
I'm assuming your ratings.csv has headers that is why this has sed 1d ratings.csv
i input command in the bash shell:
#!/bin/bash
[[ a>2 ]];echo $?
I get 0
and another command:
#!/bin/bash
[[ 3>2 ]];echo $?
I get
bash: unexpected token 283 in conditional command
bash: syntax error near `3>'
Why I get the err ?
How do I use > < in the [[ ]] ?
I am more curious, in [[]] how to use > < . [[ a>2 ]];echo $? do not add spaces, but [[ 3 > 2 ]] must be added space, more curious about the reasons
thank you!
As the man page for bash builtins states: "Each operator and operand
must be a separate argument."
Also your variable a should be $a
Here is example :
# Returns true
$ a=10; [[ "$a" -gt 1 ]]; echo "$?"
0
# Returns false
$ a=10; [[ "$a" -gt 12 ]]; echo "$?"
1
Following may help you
Integer comparison operators
| Operator | Description | Example |
|----------|-----------------------------|----------------------------------------------------------|
| -eq | Is Equal To | if [ $1 -eq 200 ] |
| -ne | Is Not Equal To | if [ $1 -ne 1 ] |
| -gt | Is Greater Than | if [ $1 -gt 15 ] |
| -ge | Is Greater Than Or Equal To | if [ $1 -ge 10 ] |
| -lt | Is Less Than | if [ $1 -lt 5 ] |
| -le | Is Less Than Or Equal To | if [ $1 -le 0 ] |
| == | Is Equal To | if (( $1 == $2 )) [Note: Used within double parentheses] |
| != | Is Not Equal To | if (( $1 != $2 )) |
| < | Is Less Than | if (( $1 < $2 )) |
| <= | Is Less Than Or Equal To | if (( $1 <= $2 )) |
| > | Is Greater Than | if (( $1 > $2 )) |
| >= | Is Greater Than Or Equal To | if (( $1 >= $2 )) |
String comparison operators
| Operator | Description | Example |
|----------|------------------------------------|-----------------|
| = or == | Is Equal To | if [ $1 == $2 ] |
| != | Is Not Equal To | if [ $1 != $2 ] |
| > | Is Greater Than (ASCII comparison) | if [ $1 > $2 ] |
| >= | Is Greater Than Or Equal To | if [ $1 >= $2 ] |
| < | Is Less Than | if [ $1 < $2 ] |
| <= | Is Less Than Or Equal To | if [ $1 <= $2 ] |
| -n | Is Not Null | if [ -n $1 ] |
| -z | Is Null (Zero Length String) | if [ -z $1 ] |
read n
i=0
sum=0
while [ $i -lt $n ]
do
read X
sum=`expr $X + $sum `
i=`expr $i + 1 `
done
echo "scale = 3; $sum/$n" | bc -l
--my above code is rounding upto a lesser value, where i want the greater one
e.g. if the ans is 4696.9466 it is rounding up to 4696.946 whereas 4696.947 is what i want. So , suggest any edits
You may pipe your bc to printf :
echo "scale = 4; $sum/$n" | bc -l | xargs printf '%.*f\n' 3
From you example :
$ echo "scale = 4; 4696.9466" | bc -l | xargs printf '%.*f\n' 3
4696,947
Change last line of your script from echo "scale = 3; $sum/$n" | bc -l to
printf %.3f $(echo "$sum/$n" | bc -l)
printf will round it off correctly. For example,
$ sum=1345
$ n=7
$ echo "$sum/$n" | bc -l
192.14285714285714285714
$ printf %.3f $(echo "$sum/$n" | bc -l)
192.143