text processing to select date range - date

I have below input and I want to select lines with dates from now to 2 weeks or 3 weeks and so on.
0029L5 08/19/2017 00:57:33
0182L5 08/19/2017 05:53:57
0183L5 02/17/2018 00:00:16
0091L5 10/19/2022 00:00:04
0045L5 07/27/2017 09:03:56
0059L5 08/14/2017 00:51:50
0100L5 08/20/2017 01:25:39
0111L5 08/21/2017 00:46:15
0128L5 08/21/2017 12:38:51
D00054 07/21/2017 09:01:19
So the desired output if let say I want for 2 weeks from now
0045L5 07/27/2017 09:03:56
D00054 07/21/2017 09:01:19
But if i want for let say 4 weeks then the output should be
0045L5 07/27/2017 09:03:56
0059L5 08/14/2017 00:51:50
D00054 07/21/2017 09:01:19

One way:
awk '{split($2,a,"/");split($3,b,":"); x=mktime(a[3]" "a[1]" "a[2]" "b[1]" "b[2]" "b[3]);y=systime();}x>y && x<(y+(n*7*24*60*60))' n=2 file
where n indicates the number of weeks
split($2,a,"/") => Split the 2nd column on the basis of / and store in array a
split($3,b,":") => Split the 3rd column on the basis of : and store in array b
mktime => gives the time in seconds
x contains the time in file in seconds
y contains the current time in seconds

Here's one solution using bash where file is the name of your file:
while read r; do dd=$(($(date -d "${r:6}" +%s) - $(date +%s))); echo $(($dd/(3600*24))); done < file
This will compute the date difference in seconds between the date in ${r:6} (substring of the current row) and today's date $(date +%s) and convert it to days.
To output only lines where the date difference is less than 2 weeks (1209600 seconds)
while read r; do dd=$(($(date -d "${r:6}" +%s) - $(date +%s))); if [ "$dd" -lt 1209600 ]; then echo $r; fi; done < file

This works fine, Please let me know in case anybody has any other simpler solution for AIX.
awk '{split($2,a,"/");split($3,b,":"); print $1,b[3],b[2],b[1],a[2],a[1],a[3]}' /tmp/TLD_1 | head -10 | while read media sec min hour day mon year; do month=$((10#$mon-1)); expiry=$(perl -e 'use Time::Local; print timegm(#ARGV[0,1,2,3], $ARGV[4], $ARGV[5]), "\n";' $sec $min $hour $day $month $year); current=$(date +%s); twoweeks=$(($current + (2*7*24*60*60))); if [ "$expiry" -gt "$current" -a "$expiry" -lt "$twoweeks" ]; then echo "$media $mon/$day/$year $hour:$min:$sec"; fi; done

Related

FFMPEG Duration convert To Frames On PowerShell

I am new to FFMPEG
I need to get some duration's of some audio and video files.
my out put comes in seconds and milliseconds i guess
I need to convert this milliseconds into frames
FrameCount should be 30
This is my code
$audioId = "$id.m4a"
$dur = ffprobe $audioId -show_format 2>&1 | sed -n 's/duration=//p'
echo $dur
Output be like, its a loop running
3.478042
3.455979
3.522021
my question is , i need to keep three seconds as it is , on the right side the milliseconds i need it to be divided by 30
that means i need the answers be like
3.15934
3.15199
3.17400
thank you
$audioId = "$id.m4a"
$dur = ffprobe $audioId -show_format 2>&1 | sed -n 's/duration=//p'
Echo ($dur.Split(".")[0] + "." + [math]::Round($dur.Split(".")[1]/30))

HRULE at MIN-value in RRDTOOL

I'm trying to get a Horizontal line (HRULE) at the lowest value in my RRD-GRAPH with out any good result :(
I have only one data source in the database, end the script is coded in PEARL
#!/usr/bin/perl
use RRDs;
my $cur_time = time();
my $start_time = $cur_time - 86400; # sätt start ill 24 timmar sedan
my $end_1 = time() - 86400;
my $start_1 = $end_1 - 86400;
RRDs::graph "/var/www/ute.png",
"--start= $start_time",
"--end= $cur_time",
"--title= outdoor temperature 1-WIRE 24h",
"--height= 600",
"--width= 1000",
"--vertical-label= °C",
"--upper-limit= 30",
"--lower-limit= -30",
"DEF:Temperatur=/home/nordviken/rrddata/ute_temp.rrd:ute:AVERAGE",
"CDEF:a=Temperatur,-50,0,LIMIT",
"DEF:b=/home/nordviken/rrddata/ute_temp.rrd:ute:AVERAGE:end= $end_1:start= $start_1",
"SHIFT:b:86400",
"COMMENT:\t\t\t\t Nu Medel Max Min\\n",
"HRULE:0#003300",
"LINE1:Temperatur#ff0000:ute\t\t\t\t",
"LINE1:a#0000ff",
"LINE1:b#00ff00",
"GPRINT:Temperatur:LAST:%6.1lf",
"GPRINT:Temperatur:AVERAGE:%6.1lf",
"GPRINT:Temperatur:MAX:%6.1lf",
"GPRINT:Temperatur:MIN:%6.1lf\\n";
my $err=RRDs::error;
if ($err) {print "problem med att skapa grafen: $err\n";}
print "klar!\n"
You could use
VDEF:m=Temperatur,MINIMUM
LINE1:m#003300

Gnuplot prints a strange year, 30 years later

I have the next problem with gnuplot, when I print the time gnuplot
prints de time+30years.
This is a part of my data:
1411336800,1390,0,0,0,10,1411,0,10,0,0,0,0,0,1411
1411340400,1506,0,0,0,10,969,0,10,0,0,0,0,0,969
1411344000,1115,0,0,0,10,1108,0,10,0,0,0,0,0,1108
1411347600,719,0,0,0,10,712,0,10,0,0,0,0,0,712
A part of the script is:
set timefmt "%s"
stats "<tail -1 uur.txt " using 1:2 nooutput
tijd = strftime("%d %B %Y %H:%M", STATS_max_x)
print tijd
And then gnuplot prints: 21 September 2044 01:00. 44 ?
Has some one a clue?
I tried several formats but nothing helped.
Until version 4.6, internally gnuplot uses the 1. January 2000 as reference for its date and time functions (in version 5.0 the standard Unix timestamp is used).
You shouldn't have any problems with set timefmt "%s" if you plot the data. But when using strftime it makes a difference. Since you're using tail anyway, you can simply use
tijd = system('date -d #$(tail -1 uur.txt | cut -d, -f1) +"%d %B %Y %H:%M"')
print tijd

How to sum values in a column grouped by values in the other

I have a large file consisting data in 2 columns
100 5
100 10
100 10
101 2
101 4
102 10
102 2
I want to sum the values in 2nd column with matching values in column 1. For this example, the output I'm expecting is
100 25
101 6
102 12
I'm trying to work on this using bash script preferably. Can someone explain me how can I do this
Using awk:
awk '{a[$1]+=$2}END{for(i in a){print i, a[i]}}' inputfile
For your input, it'd produce:
100 25
101 6
102 12
In a perl oneliner
perl -lane "$s{$F[0]} += $F[1]; END { print qq{$_ $s{$_}} for keys %s}" file.txt
You can use an associative array. The first column is the index and the second becomes what you add to it.
#!/bin/bash
declare -A columns=()
while read -r -a line ; do
columns[${line[0]}]=$((${columns[${line[0]}]} + ${line[1]}))
done < "${1}"
for idx in ${!columns[#]} ; do
echo "${idx} ${columns[${idx}]}"
done
Using awk and maintain the order:
awk '!($1 in a){a[$1]=$2; b[++i]=$1;next} {a[$1]+=$2} END{for (k=1; k<=i; k++) print b[k], a[b[k]]}' file
100 25
101 6
102 12
Python is my choice:
d = {}
for line in f.readlines():
key,value = line.split()
if d[key] == None:
d[key] = 0
d[key] += value
print d
Why would you want a bash script?

sed remove line containing a string and nothing but; automation using for loop

Q1: Sed specify the whole line and if the line is nothing but the string then delete
I have a file that contains several of the following numbers:
1 1
3 1
12 1
1 12
25 24
23 24
I want to delete numbers that are the same in each line. For that I have either been using:
sed '/1 1/d' < old.file > new.file
OR
sed -n '/1 1/!p' < old.file > new.file
Here is the main problem. If I search for pattern '1 1' that means I get rid of '1 12' as well. So for I want the pattern to specify the whole line and if it does, to delete it.
Q2: Automation of question 1
I am also trying to automate this problem. The range of numbers in the first column and the second column could be from 1 to 25.
So far this is what I got:
for ((i=1;i<26;i++)); do
sed "/'$i' '$i'/d" < oldfile > newfile; mv newfile oldfile;
done
This does nothing to the oldfile in the end. :(
This would be more readable with awk:
awk '$1 == $2 {next} {print}' oldfile > newfile
Update based on comment:
If the requirement is to remove lines where the two values are within 1 of each other:
awk '{d = $1-$2; if (-1 <= d && d <= 1) next; else print}' oldfile
Unfortunately, awk does not have abs() (at least nawk and gawk don't)
Just put the first number in a group (\([0-9]*\)) and then look for it with a backreference (\1). Since the line to delete should contain only the group, repeated, use the ^ to mark the beginning of line and the $ to mark the end of line. For example, for the following file:
$ cat input
1 1
3 1
12 1
1 12
12 12
12 13
13 13
25 24
23 24
...the result is:
$ sed '/^\([0-9]*\) \1$/d' input
3 1
12 1
1 12
12 13
25 24
23 24
You can also do it with grep:
grep -E -v "([0-9])*\s\1" testfile
Look for multiple digits in a row and remember them, followed by a single whitespace, followed by whatever digits you remembered.