1394661620440271000/1000000: No such file or directory - shell

I am running this command in my shell script to get time in milliseconds:
START=`$(date +%s%N)/1000000`
However I keep getting the error:
1394661620440271000/1000000: No such file or directory
I tried to change the code by adding brackets, extra dollar signs, but I keep getting different kinds of errors. How can I fix the code? Could anyone help with that?

assuming that you're using bash:
START=$(( $(date '+%s%N') / 1000000 ))
you can't just say / on the command line to divide numbers. (( ... )) does arithmetic evaluation in bash.

I think you want the following:
START=$(($(date +%s%N)/1000000))

You could also use plain string manipulation:
$ start=$(date '+%s%N')
$ echo $start
1394663274979099354
$ echo ${start:0:-6}
1394663274979

The printf statement can round a value to the nearest millisecond:
printf "%0.3f\n" $(date +%s.%N)

Related

How to delete folders that fail a condition in bash script

I have a number of folders that are constantly and automatically generated. Some are garbage and need to be cleared out. Each folder produces a generations.txt which I want to count the important lines to determine whether or not the folder should be deleted. I'd like to have a bash script I can run every so often to clean things up.
Here's what I have. I can echo the command I want but I don't believe it outputs the integer to compare to 5. Any suggestions would really help me out. Please and thank you!
#!/bin/bash
SEARCHABLES="grep -Evc 'Value:' "
for d in */
do
PATH=$d'generations.txt'
COMMAND=$SEARCHABLES$PATH
if $COMMAND < 5
then
rm -rf $d
fi
done
You're not getting the output of the command, you need $(...) to execute a command and substitute its output.
To perform the arithmetic comparison, you have to put it inside ((...)).
#!/bin/bash
SEARCHABLES="grep -Evc 'Value:' "
for d in */
do
PATH="$d"'generations.txt'
COMMAND=$SEARCHABLES$PATH
if (( $($COMMAND) < 5 ))
then
rm -rf "$d"
fi
done
See BashFAQ/050 - I'm trying to put a command in a variable, but the complex cases always fail!
for a more detailed explanation.
In short, embedding a command in a variable is a faulty approach to the problem here because the single quotes in 'Value:' will be treated like literal data to search for. Syntax parsing happens before expansions, so you can't embed quotes in a variable like that. What you need is a function:
_count() {
grep -Evc 'Value:' "$1"
}
_count "$PATH"
Then compare the output of the function using an arithmetic expression:
occurrences=$( _count "$PATH" )
if (( occurrences < 5 )) ; then
...
fi

Time difference between two dates in the log files

I am trying to get the time difference between two dates as given below in Bash script. However I am not successful
head_info: 05-31-2017:04:27:37
tail_info: 05-31-2017:04:30:57
the problem is that after Reformation above time and while trying to calculate in seconds due to space, it is ignoring time.
This is my script:
fm_head_info=(${head_info:6:4}"-"${head_info:0:2}"-"${head_info:3:2}" \
"${head_info:11:8})
fm_tail_info=(${tail_info:6:4}"-"${tail_info:0:2}"-"${tail_info:3:2}" \
"${tail_info:11:8})
$ fm_head_info
-bash: 2017-05-31: command not found
Thank you
Let's define your shell variables:
$ tail_info=05-31-2017:04:30:57
$ head_info=05-31-2017:04:27:37
Now, let's create a function to convert those dates to seconds-since-epoch:
$ date2sec() { date -d "$(sed 's|-|/|g; s|:| |' <<<"$*")" +%s; }
To find the time difference between those two date in seconds:
$ echo $(( $(date2sec "$tail_info") - $(date2sec "$head_info") ))
200
As written above, this requires bash (or similar advanced shell) and GNU date. In other words, this should work on any standard Linux. To make this work on OSX, some changes to the date command will likely be necessary.
How it works
Starting with the innermost command inside the function date2sec, we have:
sed 's|-|/|g; s|:| |' <<<"$*"
In the argumnet to the function, this replaces all - with / and it replaces the first : with a space. This converts the the dates from the format in your input to one that the GNU date function will understand. For example:
$ sed 's|-|/|g; s|:| |' <<<"05-31-2017:04:30:57"
05/31/2017 04:30:57
With this form, we can use date to find seconds-since-epoch:
$ date -d "05/31/2017 04:30:57" +%s
1496230257
And, for the head_info:
$ date -d "05/31/2017 04:27:37" +%s
1496230057
Now that we have that, all that is left is to subtract the times:
$ echo $(( 1496230257 - 1496230057 ))
200
Your immediate issue is the inclusion of erroneous (...) surrounding your string indexed assignment and your questionable quoting. It looks like you intended:
fm_head_info="${head_info:6:4}-${head_info:0:2}-${head_info:3:2} ${head_info:11:8}"
fm_tail_info="${tail_info:6:4}-${tail_info:0:2}-${tail_info:3:2} ${tail_info:11:8}"
Your use of string indexes is correct, e.g.
#!/bin/bash
head_info=05-31-2017:04:27:37
tail_info=05-31-2017:04:30:57
fm_head_info="${head_info:6:4}-${head_info:0:2}-${head_info:3:2} ${head_info:11:8}"
fm_tail_info="${tail_info:6:4}-${tail_info:0:2}-${tail_info:3:2} ${tail_info:11:8}"
echo "fm_head_info: $fm_head_info"
echo "fm_tail_info: $fm_tail_info"
Example Use/Output
$ bash headinfo.sh
fm_head_info: 2017-05-31 04:27:37
fm_tail_info: 2017-05-31 04:30:57
You can then do something similar with the differences in date -d "$var" +%s as John shows in his answer to arrive at the time difference. Note, string indexes are limited to bash, while a sed solution (absent the herestring) would be portable on all POSIX shells.

Bash scripts - Add value from file and subtract

I have created a script that adds seconds from 1/1 1970 to a file called datefile.txt. IT looks like this:
echo $(date +%s) > datefile.txt
What i want to do now is to read that value from datefile.txt and subtract the current value (current amount of seconds) from the previous stored in datefile.txt.
I have tried a bunch of things but I lack knowledge of bash syntax and general knowledge.
Most recent attempt:
d<datefile.txt
echo $(( d-date +%s ))
Obviously this is a retarded solution because it doesn't work.
Im running this on Ubuntu.
After doing :
echo $(date +%s) > datefile.txt
You can do this :
oldtime=$(<datefile.txt)
difference=$(( $(date +%s) - oldtime))
I assume you actually want to substract the old value from the new one to get a positive result.
The $(<datefile.txt) expands to the whole content of a file.
Also, note that when you want to use the output of a command inside an arithmetic expression, you have to enclose that command with $() (command substitution) or else the shell will not know this is a command you want to execute, as opposed to arguments that need to be read directly.

seq - invalid floating point argument error

I'm currently writing a small bash file to search specific information on a file.
I need a for structure and I'm using "seq" but I keep getting "invalid floating point argument error : 4" and I do not know how to solve it.
When I try to do some arithmetic operation on my variable nmbretry, I get a arithmetic operator not available.
If you have any ideas how to solve it!
Here my code:
#!/bin/bash
nmbretry=`grep -c 'retry for the 1 times' /home/leconte/dossierpartage/business.log`
echo "Number of retry is $nmbretry"
let $nmbretry + 1
for i in `seq 0 $nmbretry`; do echo $i
done;
Thanks a lot!
increment nmbretry with let ++nmbretry - bash also has a counted for loop:
for((i=0; i < nmbretry; ++i)); do
echo $i
done
Thanks for your help.
The error was that I used notepad on Windows than use it on Unix. It did not like the "transfer".
I do everything on Unix and now it's work!
Thanks again.

how to repeat an executable with different parameters?

I have an executable file to analyse an image . In the shell I write ./analyse img_001.jpg and it returns 1 number.
I looked for a solution to analyse my 999 images ( img_001.jpg to img_999.jpg) with the use of a script ( i don't really wish to do it manually ) and I need a hint please.
Is it possible to have something like ./script.sh that returns me the 999 numbers?
Cordially
If you are using bash, you can simply use brace expansion:
for i in {1..999}; do
printf "img_%03d.jpg\n" $i
done
This will print out:
img_001.jpg
img_002.jpg
...
img_998.jpg
img_999.jpg
To run your script using these as arguments you can use:
for i in {1..999}; do
./analyse $(printf "img_%03d.jpg" $i)
done
You could also replace the brace expansion with seq:
for i in $(seq 1 999); do

Resources