(standard_in) 1: syntax error on script that should work - bash

I've downloaded a script from github, which seems to work, but I'm getting the error when running.
https://github.com/chentda/curl-average-timings
The script calculates the average loading time from a URL
#!/bin/bash
#This is a simple bash script to get the averages of various website response timings using cURL
#Formatted cURL output that contains the various response timings separated by '-'
curl_format="%{time_namelookup}-%{time_connect}-%{time_appconnect}-%{time_pretransfer}-%{time_redirect}-%{time_starttransfer}-%{time_total}"
#Website you want to send the request to
URL="https://www.google.com/"
#How many requests you want to hit website with to get averages
iterations=5
decimal_rounding=5
#Initialising total variables for the various timings
total_time_namelookup="0"
total_time_connect="0"
total_time_appconnect="0"
total_time_pretransfer="0"
total_time_redirect="0"
total_time_starttransfer="0"
total_time_total="0"
for i in `seq 1 $iterations`;
do
response=$(curl -o /dev/null -s -w $curl_format $URL)
#Splits response string by the delimiter of "-"
response_times=($(echo "$response" | tr "-" "\n"))
#Assigning each type of response time to a variable
time_namelookup=${response_times[0]}
time_connect=${response_times[1]}
time_appconnect=${response_times[2]}
time_pretransfer=${response_times[3]}
time_redirect=${response_times[4]}
time_starttransfer=${response_times[5]}
time_total=${response_times[6]}
#Adding variables assigned above in loop to the respective total variables that are set at start of script
total_time_namelookup=$(echo "$total_time_namelookup + $time_namelookup" | bc)
total_time_connect=$(echo "$total_time_connect + $time_connect" | bc)
total_time_appconnect=$(echo "$total_time_appconnect + $time_appconnect" | bc)
total_time_pretransfer=$(echo "$total_time_pretransfer + $time_pretransfer" | bc)
total_time_redirect=$(echo "$total_time_redirect + $time_redirect" | bc)
total_time_starttransfer=$(echo "$total_time_starttransfer + $time_starttransfer" | bc)
total_time_total=$(echo "$total_time_total + $time_total" | bc)
done
#Calculating the average for each type of response time
average_time_namelookup=$(echo "scale=$decimal_rounding; $total_time_namelookup / $iterations" | bc)
average_time_connect=$(echo "scale=$decimal_rounding; $total_time_connect / $iterations" | bc)
average_time_appconnect=$(echo "scale=$decimal_rounding; $total_time_appconnect / $iterations" | bc)
average_time_pretransfer=$(echo "scale=$decimal_rounding; $total_time_pretransfer / $iterations" | bc)
average_time_redirect=$(echo "scale=$decimal_rounding; $total_time_redirect / $iterations" | bc)
average_time_starttransfer=$(echo "scale=$decimal_rounding; $total_time_starttransfer / $iterations" | bc)
average_time_total=$(echo "scale=$decimal_rounding; $total_time_total / $iterations" | bc)
echo "Averages of response timings:"
echo ""
echo " time_namelookup: $average_time_namelookup"
echo " time_connect: $average_time_connect"
echo " time_appconnect: $average_time_appconnect"
echo " time_pretransfer: $average_time_pretransfer"
echo " time_redirect: $average_time_redirect"
echo "time_starttransfer: $average_time_starttransfer"
echo " --------"
echo " time_total: $average_time_total"
After a few debuggin, I can see that the problem is on this line, when uses bc to sum results
total_time_namelookup=$(echo "$total_time_namelookup + $time_namelookup" | bc)
But it throws
(standard_in) 1: syntax error
But I can't figure what I'm doing wrong.
I'm on ubuntu running from the terminal with sh

Your numeric values contains a locale specific decimal separator (,). bc only knows .. Convert your string containing numeric values by running them through tr , '.' before sending them to bc.
Or, as suggested by tripleee, set the C locale explicitly at the top of the script:
export LC_ALL=C
For more complex locale operations, you may need library support:
https://github.com/leagris/lcnumconv.sh

Related

Trouble making mathematical operations with big hexadecimal numbers on bash

I'm trying to perform multiple mathematical operations with big hexadecimal numbers. In the following code a big random value is given to p and q, both variables are multiplied together making the result the value of n. Then make a subtraction "(n-2)" but when subtracting 2 to n the result seems like being wrong
#!/bin/bash
generate_random() {
head -c 256 /dev/urandom | xxd -p -u -c 256 | tr -d '[:space:]\\'
}
p="$(generate_random)"
q="$(generate_random)"
n=$(echo "${p} * ${q}" | tr -d '[:space:]\\')
echo "obase=16; ${n} - 2" | bc | tr -d '[:space:]]\\'
I'm using this webstie to check the results and so far I haven't managed to get any correct output from my script
Value examples:
Generated value for p
28DA11279C9BF6B6A93CF1288C63845503D87C17C93554421C3069A5283547CEE4C127F3289BDC03663143808B7318B321B35B25ECC6D48EF60283DA6111104291070E3FBEDBD27A942D2B3630AA8683C6BB4F6F6EE277A24A4C9B93AEEB61D48AC7657FA6E61DC95A8EF133F97C6ED3B285E275487746F070005B2BCDEA9C7C12F294DFCE55BC7013417F8E47CEC605F13AFD5C54A3578BB041278285511248E975FE29F4013CA059599EE95E43E28B886D0651EFDDFF760DBB298096C7CA1A46FE3D119914C23ABA5543C43BE546FA70D7FA36B22DA17210A6CABDCD299751ADEE381A3230E9978946B193AB02921947887A2FC7A5DC84D2193F9CFC865B52
Generated value for q
54DEBA70F8F052F5120B77254EB999E12180241520DC2A12F62F6773992155AEFC5356E3F9B3271FE5AA9D425F7D2CD8233196C98595F993899C31D4063F75A801D1752AD178663E3CDF3CF38CEE1972C861DC6069B787249963D305E4FC970A48E67D3A680CD58F17229379EAE5445603E50E60CF605F1057766EFEAFAA2299CCBC0C4F161815DBD06294E4BBD43EF55F1E2D7544B39279EA4B9114AB9F9D0FC2B46135911CF62FB4A22A615936FDDAD23131B1F0AD2FB94D44C0879B3289530653C4714B2E3F3F9FFD17E92C44FBCE589982F68985207F788FBD1B531C56224E4EDA1F124E6AEC19C949AB396862F0856C435EBAAAB7FFB1251FBEB338676D
Result of n
28DA11279C9BF6B6A93CF1288C63845503D87C17C93554421C3069A5283547CEE4C127F3289BDC03663143808B7318B321B35B25ECC6D48EF60283DA6111104291070E3FBEDBD27A942D2B3630AA8683C6BB4F6F6EE277A24A4C9B93AEEB61D48AC7657FA6E61DC95A8EF133F97C6ED3B285E275487746F070005B2BCDEA9C7C12F294DFCE55BC7013417F8E47CEC605F13AFD5C54A3578BB041278285511248E975FE29F4013CA059599EE95E43E28B886D0651EFDDFF760DBB298096C7CA1A46FE3D119914C23ABA5543C43BE546FA70D7FA36B22DA17210A6CABDCD299751ADEE381A3230E9978946B193AB02921947887A2FC7A5DC84D2193F9CFC865B52*54DEBA70F8F052F5120B77254EB999E12180241520DC2A12F62F6773992155AEFC5356E3F9B3271FE5AA9D425F7D2CD8233196C98595F993899C31D4063F75A801D1752AD178663E3CDF3CF38CEE1972C861DC6069B787249963D305E4FC970A48E67D3A680CD58F17229379EAE5445603E50E60CF605F1057766EFEAFAA2299CCBC0C4F161815DBD06294E4BBD43EF55F1E2D7544B39279EA4B9114AB9F9D0FC2B46135911CF62FB4A22A615936FDDAD23131B1F0AD2FB94D44C0879B3289530653C4714B2E3F3F9FFD17E92C44FBCE589982F68985207F788FBD1B531C56224E4EDA1F124E6AEC19C949AB396862F0856C435EBAAAB7FFB1251FBEB338676D
Expected value for n
d8b187c5754df9d215796bcae5b552e87d4f7a590bb257a208e327cb1e3bf48cbefba07388a0a49f1782f78a232147e9b1137b4eb54611200eab02faa0edd005ee52a33832d391b0aa766fdca712a441a26586fa9418b791e71056117bbf80b07ab68502491a5b70222ad058fdd733b30701f0b46cf7486d8a412096d4a05f43b5c58052baadd51bb08aadf551366513fde427d4fd1ac35778762cd960d3697f4a661b7dda642e5e71284d9fca947171cba5b5e9387cfa078833c3ace7c42baced889cdda8744b021524aec2ed20ef0e0379cf03b206ed0707917c0f38ef66fb79f4198bb1d25c046901b3f54a2910b90ba3b595511042cd682ba38eab459b77b41a37c05d3cffda58346d8dc7bf180ec72aa7b4c4e0cb532c4f374e7bec1e5e970d129dd755a38ca070dd700b5133a3d0c8ba5fbab7c309b94480aa9996d762c1c3cb87170dda878bc9c51db4573681e8dd57db6f4bb1375f386323f643045fef1391498ca7fcca8fe830f6e268db877d7950861a7ab661cb63ab7831934b5a2bdacf53d3c7eac80e1130f786e1b95b5b3f98374ced618a36bb5b3ceab60861ddbb7ae227e9d2abc26931e55483a6a4e891ef54f786519c7250e70a39b821602eb5820fcc4422215452e3a6355140af77697e752aced92cc778e4c6d4df3d8a230a8a8e4756e5f5e347ab0d9bab51f1dc25b5d6099246ae1e2238be3e2dfea
Since the input is in hexadecimal you should also use ibase.
#!/bin/bash
generate_random() {
head -c 256 /dev/urandom | xxd -p -u -c 256 | tr -d '[:space:]\\'
}
p="$(generate_random)"
q="$(generate_random)"
n=$(echo "${p} * ${q}" | tr -d '[:space:]\\')
echo "obase=16;ibase=16; ${n} - 2" | bc | tr -d '[:space:]]\\'
The result in the case you posted is -
D8B187C5754DF9D215796BCAE5B552E87D4F7A590BB257A208E327CB1E3BF48CBEFBA07388A0A49F1782F78A232147E9B1137B4EB54611200EAB02FAA0EDD005EE52A33832D391B0AA766FDCA712A441A26586FA9418B791E71056117BBF80B07AB68502491A5B70222AD058FDD733B30701F0B46CF7486D8A412096D4A05F43B5C58052BAADD51BB08AADF551366513FDE427D4FD1AC35778762CD960D3697F4A661B7DDA642E5E71284D9FCA947171CBA5B5E9387CFA078833C3ACE7C42BACED889CDDA8744B021524AEC2ED20EF0E0379CF03B206ED0707917C0F38EF66FB79F4198BB1D25C046901B3F54A2910B90BA3B595511042CD682BA38EAB459B77B41A37C05D3CFFDA58346D8DC7BF180EC72AA7B4C4E0CB532C4F374E7BEC1E5E970D129DD755A38CA070DD700B5133A3D0C8BA5FBAB7C309B94480AA9996D762C1C3CB87170DDA878BC9C51DB4573681E8DD57DB6F4BB1375F386323F643045FEF1391498CA7FCCA8FE830F6E268DB877D7950861A7AB661CB63AB7831934B5A2BDACF53D3C7EAC80E1130F786E1B95B5B3F98374CED618A36BB5B3CEAB60861DDBB7AE227E9D2ABC26931E55483A6A4E891EF54F786519C7250E70A39B821602EB5820FCC4422215452E3A6355140AF77697E752ACED92CC778E4C6D4DF3D8A230A8A8E4756E5F5E347AB0D9BAB51F1DC25B5D6099246AE1E2238BE3E2DFE8
This can be confirmed using python
In [1]: hex(0x28DA11279C9BF6B6A93CF1288C63845503D87C17C93554421C3069A5283547CEE4C127F3289BDC03663143808B7318B321B35B25ECC6D48EF60283DA6111104291070E3FBEDBD27A942D2B3630AA8683C6BB4F6F6EE277A24A4C9B93AEEB61D48AC7657F
...: A6E61DC95A8EF133F97C6ED3B285E275487746F070005B2BCDEA9C7C12F294DFCE55BC7013417F8E47CEC605F13AFD5C54A3578BB041278285511248E975FE29F4013CA059599EE95E43E28B886D0651EFDDFF760DBB298096C7CA1A46FE3D119914C23ABA5543
...: C43BE546FA70D7FA36B22DA17210A6CABDCD299751ADEE381A3230E9978946B193AB02921947887A2FC7A5DC84D2193F9CFC865B52*0x54DEBA70F8F052F5120B77254EB999E12180241520DC2A12F62F6773992155AEFC5356E3F9B3271FE5AA9D425F7D2CD82
...: 33196C98595F993899C31D4063F75A801D1752AD178663E3CDF3CF38CEE1972C861DC6069B787249963D305E4FC970A48E67D3A680CD58F17229379EAE5445603E50E60CF605F1057766EFEAFAA2299CCBC0C4F161815DBD06294E4BBD43EF55F1E2D7544B3927
...: 9EA4B9114AB9F9D0FC2B46135911CF62FB4A22A615936FDDAD23131B1F0AD2FB94D44C0879B3289530653C4714B2E3F3F9FFD17E92C44FBCE589982F68985207F788FBD1B531C56224E4EDA1F124E6AEC19C949AB396862F0856C435EBAAAB7FFB1251FBEB3386
...: 76D-2)
Out[1]: '0xd8b187c5754df9d215796bcae5b552e87d4f7a590bb257a208e327cb1e3bf48cbefba07388a0a49f1782f78a232147e9b1137b4eb54611200eab02faa0edd005ee52a33832d391b0aa766fdca712a441a26586fa9418b791e71056117bbf80b07ab68502491a5b70222ad058fdd733b30701f0b46cf7486d8a412096d4a05f43b5c58052baadd51bb08aadf551366513fde427d4fd1ac35778762cd960d3697f4a661b7dda642e5e71284d9fca947171cba5b5e9387cfa078833c3ace7c42baced889cdda8744b021524aec2ed20ef0e0379cf03b206ed0707917c0f38ef66fb79f4198bb1d25c046901b3f54a2910b90ba3b595511042cd682ba38eab459b77b41a37c05d3cffda58346d8dc7bf180ec72aa7b4c4e0cb532c4f374e7bec1e5e970d129dd755a38ca070dd700b5133a3d0c8ba5fbab7c309b94480aa9996d762c1c3cb87170dda878bc9c51db4573681e8dd57db6f4bb1375f386323f643045fef1391498ca7fcca8fe830f6e268db877d7950861a7ab661cb63ab7831934b5a2bdacf53d3c7eac80e1130f786e1b95b5b3f98374ced618a36bb5b3ceab60861ddbb7ae227e9d2abc26931e55483a6a4e891ef54f786519c7250e70a39b821602eb5820fcc4422215452e3a6355140af77697e752aced92cc778e4c6d4df3d8a230a8a8e4756e5f5e347ab0d9bab51f1dc25b5d6099246ae1e2238be3e2dfe8'
Not sure what is the calculator you're using but it has a different calculation for some reason.

how calculated in bash atan2

hello i want to calcul the distance between me and the ISS so this my code
i want to print this sentence :
The ISS is currently located at -30.1461, -50.7975: 10010km from us!
my code :
#!/bin/bash
pi = 3.14
earthRadiumKm=6371
lat2=48.813875
on2=2.392521
com=$( curl -s 'aletum.jails.simplerezo.com/etna-iss.json' | sed s/\"//g | awk\ -v RS =',' -F: '{print $1 $2 $3}' )
lat1=$( echo $com | cut c-60-66)
lon1=$( echo $com | cut c-42-50)
dLat=$( echo "($lat2 - $lat1) * $pi / 180" | bc -l)
dLat=$( echo "($lon2 - $lon1) * $pi / 180" | bc -l)
l1=$( echo "($lat1) * $pi / 180" | bcc -l)
l2=$( echo "($lat2) * $pi / 180" | bcc -l)
a=$( echo "sinus($dLat / 2) * sinus(dLat / 2) + sinus(dLon / 2) * sinus(dLon / 2) * cosine($l1) * consine($l2) | bc -l)
result=$( echo "2 * atan2(sqrt($a), sqrt(1-$a)) * $earthRaduisKm" | bc -1)
echo "The ISS is currently located at $dLat, $dLon, : ${result}KM from us!"
my Problem is my calcul are false because the result echo 0.6 km and that is impossible i thinks it's because i don't know how to use atan2
Fun little project. I have no idea if your math is right, but your code is quite terribly wrong:
no spaces around the = in an assignment: pi = 3.14 => pi=3.14
spelling error for variable names: earthRadiumKm=... => $earthRaduisKm
incorrect bc function names
incorrect system command names: awk\ -v, bcc -l
unclosed quoted string
Refactored:
#!/bin/bash
read lon1 lat1 time < <(
curl -s 'aletum.jails.simplerezo.com/etna-iss.json' |
jq -r '"\(.iss_position.longitude) \(.iss_position.latitude) \(.timestamp)"'
)
lon2=2.392521
lat2=48.813875
{ read dLat; read dLon; read result; } < <(
bc -l <<END
pi = (4*a(1/5) - a(1/239))*4
earthrad = 6371
dlat = ($lat2 - $lat1) * pi/180
dlon = ($lon2 - $lon1) * pi/180
a = s(dlat/2) * s(dlat/2) + s(dlon/2) * s(dlon/2) * c($lat1 * pi/180) * c($lat2 * pi/180)
result = 2 * a( sqrt(a) / sqrt(1-a) ) * earthrad
dlat
dlon
result
END
)
printf "At %s,\n the ISS is currently located at %.4f,%.4f : %.2f KM from us\n" \
"$(date -d "#$time" "+%F %T %Z")" \
"$dLat" "$dLon" "$result"
result
At 2018-09-12 08:53:32 EDT,
the ISS is currently located at 0.5916,-2.2398 : 11296.11 KM from us
Notes:
repeat, I have no idea if your math is right
Process Substitutions to execute some code and read the results into variables.
use jq to parse JSON
I pushed all the math into a single bc call.
bc -l uses s for sine, c for cosine and a for arctan: read the bc man page
bc has no arctan2 function
I use a formula to get pi a little more precise
bc variable names must be all lowercase.

how to use shell script to convert row to column or some nice table

I got the following script from stack overflow :
#!/bin/sh
in_file=temp2.txt # Input file
params=6 # Parameters count
res_file=$(mktemp) # Temporary file
sep=' ' # Separator character
# Print header
cnt=0
for i in $(cat $in_file | head -$((params*2))); do
if [ $((cnt % 2)) -eq 0 ]; then
echo $i
fi
cnt=$((cnt+1))
done | sed ":a;N;\$!ba;s/\n/$sep/g" >>$res_file
# Parse and print values
cnt=0
for i in $(cat $in_file); do
# Print values, skip param names
if [ $((cnt % 2)) -eq 1 ]; then
echo -n $i >>$res_file
fi
if [ $(((cnt+1) % (params*2))) -eq 0 ]; then
# Values line is finished, print newline
echo >>$res_file
elif [ $((cnt % 2)) -eq 1 ]; then
# More values expected to be printed on this line
echo -n "$sep" >>$res_file
fi
cnt=$((cnt+1))
done
# Make nice table format
cat $res_file | column -t
#rm -f $res_file
But then i have about 100 + lines in it and i'm getting a error**"column: line too long"** as below :
****column: line too long**** GigabitEthernet0/0 GigabitEthernet1/0/3 GigabitEthernet1/0/5 GigabitEthernet1/0/10
GigabitEthernet1/0/19 GigabitEthernet1/0/33 GigabitEthernet1/0/2
GigabitEthernet1/0/4 GigabitEthernet1/0/7 GigabitEthernet1/0/18
GigabitEthernet1/0/30 GigabitEthernet1/0/44 GigabitEthernet1/0/46
GigabitEthernet1/1/3 GigabitEthernet2/0/1 GigabitEthernet2/0/5
GigabitEthernet2/0/9 GigabitEthernet2/0/14 GigabitEthernet2/0/18
GigabitEthernet2/0/31 GigabitEthernet2/0/34 GigabitEthernet2/0/36
GigabitEthernet2/0/40 GigabitEthernet2/1/3 GigabitEthernet3/0/12
GigabitEthernet3/0/30 GigabitEthernet3/0/32 GigabitEthernet3/0/34
GigabitEthernet3/0/36 GigabitEthernet3/0/38 GigabitEthernet3/0/40
GigabitEthernet3/0/42 GigabitEthernet3/0/44 GigabitEthernet3/0/46
GigabitEthernet3/0/48 GigabitEthernet3/1/2
Any solutions you can give, i could not find the author of this script again here to ask him on this can be avoided.
Input file will be something like this :
{
GigabitEthernet0/0
GigabitEthernet1/0/2
GigabitEthernet1/0/3
GigabitEthernet1/0/4
GigabitEthernet1/0/5
GigabitEthernet1/0/7
GigabitEthernet1/0/10
GigabitEthernet1/0/18
GigabitEthernet1/0/19
GigabitEthernet1/0/30
GigabitEthernet1/0/33
GigabitEthernet1/0/44
GigabitEthernet1/0/45
GigabitEthernet1/0/46
GigabitEthernet1/1/2
GigabitEthernet1/1/3
GigabitEthernet1/1/4
GigabitEthernet2/0/1
GigabitEthernet2/0/2
GigabitEthernet2/0/5
GigabitEthernet2/0/8
GigabitEthernet2/0/9
GigabitEthernet2/0/12
GigabitEthernet2/0/14
GigabitEthernet2/0/15
GigabitEthernet2/0/18
GigabitEthernet2/0/22
GigabitEthernet2/0/31
GigabitEthernet2/0/33
GigabitEthernet2/0/34
GigabitEthernet2/0/35
GigabitEthernet2/0/36
GigabitEthernet2/0/38
GigabitEthernet2/0/40
GigabitEthernet2/1/2
GigabitEthernet2/1/3
GigabitEthernet2/1/4
GigabitEthernet3/0/12
GigabitEthernet3/0/23
GigabitEthernet3/0/30
GigabitEthernet3/0/31
GigabitEthernet3/0/32
GigabitEthernet3/0/33
GigabitEthernet3/0/34
GigabitEthernet3/0/35
GigabitEthernet3/0/36
GigabitEthernet3/0/37
GigabitEthernet3/0/38
GigabitEthernet3/0/39
GigabitEthernet3/0/40
GigabitEthernet3/0/41
GigabitEthernet3/0/42
GigabitEthernet3/0/43
GigabitEthernet3/0/44
GigabitEthernet3/0/45
GigabitEthernet3/0/46
GigabitEthernet3/0/47
GigabitEthernet3/0/48
GigabitEthernet3/1/1
GigabitEthernet3/1/2
GigabitEthernet3/1/3
GigabitEthernet3/1/4
}
Output i need something like this :
{
GigabitEthernet0/0 | GigabitEthernet1/0/33 |
GigabitEthernet1/0/2 | GigabitEthernet1/0/44 |
GigabitEthernet1/0/3 | GigabitEthernet1/0/43 |
GigabitEthernet1/0/4 | GigabitEthernet1/0/46 |
GigabitEthernet1/0/5 | GigabitEthernet1/1/2 |
GigabitEthernet1/0/7 | GigabitEthernet1/1/3 |
GigabitEthernet1/0/10| GigabitEthernet1/1/4 |
GigabitEthernet1/0/18| GigabitEthernet2/0/1 |
GigabitEthernet1/0/19| GigabitEthernet2/0/2 |
GigabitEthernet1/0/30| GigabitEthernet2/0/5 |
}
I have got this resolved using a column command.
it just posts the output something like this
column vacant_temp4.txt
GigabitEthernet1/0/1 GigabitEthernet1/0/48 GigabitEthernet2/0/34 GigabitEthernet3/0/44 GigabitEthernet4/0/28
GigabitEthernet1/0/2 GigabitEthernet1/1/2 GigabitEthernet2/0/35 GigabitEthernet3/1/1 GigabitEthernet4/0/29
GigabitEthernet1/0/3 GigabitEthernet1/1/3 GigabitEthernet2/0/36 GigabitEthernet3/1/2 GigabitEthernet4/0/30
GigabitEthernet1/0/5 GigabitEthernet1/1/4 GigabitEthernet2/0/38 GigabitEthernet3/1/3 GigabitEthernet4/0/31
GigabitEthernet1/0/7 GigabitEthernet2/0/1 GigabitEthernet2/0/45 GigabitEthernet3/1/4 GigabitEthernet4/0/32
GigabitEthernet1/0/8 GigabitEthernet2/0/5 GigabitEthernet2/1/2 GigabitEthernet4/0/1 GigabitEthernet4/0/33
GigabitEthernet1/0/9 GigabitEthernet2/0/8 GigabitEthernet2/1/3 GigabitEthernet4/0/5 GigabitEthernet4/0/34
GigabitEthernet1/0/14 GigabitEthernet2/0/9 GigabitEthernet2/1/4 GigabitEthernet4/0/6 GigabitEthernet4/0/35
GigabitEthernet1/0/16 GigabitEthernet2/0/10 GigabitEthernet3/0/2 GigabitEthernet4/0/9 GigabitEthernet4/0/36
GigabitEthernet1/0/19 GigabitEthernet2/0/13 GigabitEthernet3/0/5 GigabitEthernet4/0/12 GigabitEthernet4/0/37
GigabitEthernet1/0/20 GigabitEthernet2/0/14 GigabitEthernet3/0/7 GigabitEthernet4/0/13 GigabitEthernet4/0/38
GigabitEthernet1/0/26 GigabitEthernet2/0/16 GigabitEthernet3/0/13 GigabitEthernet4/0/16 GigabitEthernet4/0/39
GigabitEthernet1/0/27 GigabitEthernet2/0/20 GigabitEthernet3/0/16 GigabitEthernet4/0/17 GigabitEthernet4/0/40
GigabitEthernet1/0/28 GigabitEthernet2/0/21 GigabitEthernet3/0/19 GigabitEthernet4/0/18 GigabitEthernet4/0/41
GigabitEthernet1/0/30 GigabitEthernet2/0/25 GigabitEthernet3/0/22 GigabitEthernet4/0/19 GigabitEthernet4/0/42
GigabitEthernet1/0/31 GigabitEthernet2/0/26 GigabitEthernet3/0/25 GigabitEthernet4/0/20 GigabitEthernet4/1/1
GigabitEthernet1/0/35 GigabitEthernet2/0/27 GigabitEthernet3/0/26 GigabitEthernet4/0/21 GigabitEthernet4/1/2
GigabitEthernet1/0/36 GigabitEthernet2/0/28 GigabitEthernet3/0/27 GigabitEthernet4/0/22 GigabitEthernet4/1/3
GigabitEthernet1/0/37 GigabitEthernet2/0/29 GigabitEthernet3/0/37 GigabitEthernet4/0/23 GigabitEthernet4/1/4
GigabitEthernet1/0/40 GigabitEthernet2/0/30 GigabitEthernet3/0/39 GigabitEthernet4/0/24
GigabitEthernet1/0/45 GigabitEthernet2/0/31 GigabitEthernet3/0/41 GigabitEthernet4/0/26
GigabitEthernet1/0/46 GigabitEthernet2/0/32 GigabitEthernet3/0/42 GigabitEthernet4/0/27
It looked better than what you saw above on my putty screen .
Thank you oliv , tripleee , paul & all.

unix find the difference from a file row wise

I have some data like
[09359]0000.365604| =>SttSasph_Hmbm_bSPO_PhQmOm (Hmbm_PhQmOm_utWmP.asp)
[09359]0000.365687| =>Hmbm_bSPO_PhQmOm_Wd (Hmbm_PhQmOm_utWmP.asp)
[09359]0000.365879| =>SttSasph_Hmbm_quOuO_PhQmOm (Hmbm_PhQmOm_utWmP.asp)
[09359]0000.365890| =>Hmbm_quOuO_PhQmOm_Wd (Hmbm_PhQmOm_utWmP.asp)
[09359]0000.365979| WSmmOT SDDQ vSQWSbmO not POt, QOvOQtWnH to Onv mOthod
[09359]0001.625300| db_HOt_POPPWon_Wd: aspuQQOnt POPPWon WD WP 1016,59
[09359]0002.365979| WSmmOT SDDQ vSQWSbmO not POt, QOvOQtWnH to Onv mOthod
Every Line starts with a process number (Which can change) in square brackets
Then Seconds after the module (0001) in this case
Then MicroSeconds after the fullstop.
Then a Pipe to terminate.
Rest part can be ignored
What I need is to caluclate
Convert Seconds into MircoSeconds
Add the Microsconds to Converted Microseconds (From 1)
Find out the difference in microseconds. for eg. line2-line1 , line3-line2, line4- line3 and so.
Print the result in seperate file.
I tried to use this logic. But, it didnt work.
May I get suggestions with optimised way to do it or
improvement in my existing logic
sec=$(grep '^\[.\{1,\}\]' mass.May28.1 | cut -d "| " -f1 | cut -c8- | cut -d"." -f1)
msec=$(grep '^\[.\{1,\}\]' mass.May28.1 | cut -d "| " -f1 | cut -c8- | cut -d"." -f2)
$f_msec=$((sec * 1000000 + msec)) > final_difference_file
If you are comfortable with awk, then you can use this script:
script.awk
BEGIN{ FS="[\\[\\]\\|]+" }
{ printf("[%s]%011.6f|%s\n", $2,$3-prev,$4)
prev = $3 }
Use it like this: awk -f script.awk yourfile
The first line setups the fieldsplitting to use the brackets and pipe (ignore the backslashes they are need to escape the symbols that are regexp metacharacters). The second line prints the fields and calculates the timediff. The last line stores the current time for the calculation in the next line.
This can also be done with a bash script. Since bash lacks floating point arithmetic, we have to gather seconds and microseconds seperately (or call an external tool like bc for each line):
script.sh
IFS='|[].'
factor=1000000
prev=0
while read dummy pid secs msecs text;
do
msecs=$(( $secs * $factor + $msecs ))
timediff=$(( $msecs - $prev ))
prev=$msecs
secs=$(( $timediff / $factor ))
msecs=$(( $timediff - $secs * $factor ))
printf "[%s]%04d.%06d|%s\n" "$pid" "$secs" "$msecs" "$text"
done
Use it like this: bash script.sh yourfile

How to add two time outputs in bash

I want to calculate in bash the average time spent by several commands. The output of time command is min:sec.milisec.
I don't know how to add two outputs of this kind in bash and in final to calculate the average.
I tried to convert the output with date but the output is "date: invalid date `0:01.00'".
This is a three part answer
Part one
First, use the TIMEFORMAT variable to output only seconds elapsed. Then you can add this directly
From man bash
TIMEFORMAT
The value of this parameter is used as a format string specifying how the timing information
for pipelines prefixed with the time reserved word should be displayed. The % character
introduces an escape sequence that is expanded to a time value or other information. The
escape sequences and their meanings are as follows; the braces denote optional portions.
Here is an example which outputs only seconds with a precision of 0, i.e. no decimal point. Read part three why that's important.
TIMEFORMAT='%0R'; time sleep 1
1
Part two
Second, how do we capture the output of time? It's actually a bit tricky, here's how you do capture the time from the command above
TIMEFORMAT='%0R'; time1=$( { time sleep 1; } 2>&1 )
Part three
How do we add the times together and get the average?
In bash we use the $(( )) construct to do math. Note that bash does not natively support floating point so you will be doing integer division (hence the precision 0.) Here is a script that will capture the time from two commands and output each of the individual times and their average
#!/bin/bash
TIMEFORMAT='%0R'
time1=$( { time sleep 1; } 2>&1 )
time2=$( { time sleep 4; } 2>&1 )
ave=$(( (time1 + time2) / 2))
echo "time1 is $time1 | time2 is $time2 | average is $ave"
Output
time1 is 1 | time2 is 4 | average is 2
If integer division is a non-starter for you and you want precision, as long as you don't mind calling the external binary bc, you can do this quite easily.
#!/bin/bash
TIMEFORMAT='%3R'
time1=$( { time sleep 1; } 2>&1 )
time2=$( { time sleep 4; } 2>&1 )
ave=$( bc <<<"scale=3; ($time1 + $time2)/2" )
echo "time1 is $time1 | time2 is $time2 | average is $ave"
Output
time1 is 1.003 | time2 is 4.003 | average is 2.503
For the example i'll use a variable preinitialized:
time="54:32.96";
minutes=$(echo "$time" | cut -d":" -f1)
seconds=$(echo "$time" | cut -d":" -f2 | cut -d"." -f1)
millis=$(echo "$time" | cut -d":" -f2 | cut -d"." -f2)
#Total time in millis
totalMillisOne=$(($millis+$seconds*1000+$minutes*60000))
You do this with every command and you save it in diferent vars, and then you do the average:
let avMillis=$totalMillisOne+$totalMillisTwo
let avMillis=$avMillis/2
And you output it in the same input format:
let avSeconds=$avMillis/1000
let avMillis=$avMillis-$avSeconds*1000;
let avMinutes=$avSeconds/60;
let avSeconds=$avSeconds-$avMinutes*60;
echo "${avMinutes}:${avSeconds}.${avMillis}"

Resources