say that i am trying to do a echo TZ=GMT-24 date +%Y%m%d >> echoed.
This is in solaris.
Now, i would like to do a loop that reads a specific number of days and echoes with GMT-24/GMT-48 etc... until the number of days ends... this is a 5 times loop.... basicly from monday to friday. i will set this script on crontab that will run in one day and generates that echo output to a file so other script that i already have created can check those dates and work with them.
thanks in advance
This is ksh on Solaris 8:
$ date +%Y%m%d
20130919
$ for i in 1 2 3 4 5; do TZ=GMT-$(($i * 24)) date +%Y%m%d; done
20130920
20130921
20130922
20130923
20130924
$ for i in 1 2 3 4 5; do TZ=GMT+$(($i * 24)) date +%Y%m%d; done
20130918
20130917
20130916
20130915
20130914
To redirect to a file, add > filename after the done keyword
Related
I have a file named dates.txt which contains the following:
DATE_1
DATE_2
DATE_3
DATE_4
DATE_5
DATE_6
DATE_7
I just want to replace DATE_i with some dates that are stored in v array using sed command.
To do that I tried a for loop and a sed command (file test.sh):
#!/bin/bash
v[1]=`date -d "7 days ago" '+%d\/%m\/%y'`
v[2]=`date -d "6 days ago" '+%d\/%m\/%y'`
v[3]=`date -d "5 days ago" '+%d\/%m\/%y'`
v[4]=`date -d "4 days ago" '+%d\/%m\/%y'`
v[5]=`date -d "3 days ago" '+%d\/%m\/%y'`
v[6]=`date -d "2 days ago" '+%d\/%m\/%y'`
v[7]=`date -d "1 days ago" '+%d\/%m\/%y'`
cat dates.txt|for j in {1..7};do sed "s/DATE_$j/${v[$j]}/";done
The problem is that this command replaces only the first date. If you run test.sh:
$ ./test.sh
14/03/16
DATE_2
DATE_3
DATE_4
DATE_5
DATE_6
DATE_7
The output I am expecting is:
14/03/16
15/03/16
16/03/16
17/03/16
18/03/16
19/03/16
20/03/16
I cannot understand why this is not working.
Could anyone please explain why this is happening and propose a proper solution for this problem?
Thanks!!
Explanation: What's happening is that the first iteration of the for loop is consuming all of the lines you're piping to its standard input. First of all, let's modify test.sh to contain an echo statement in the last line so that we can see what's happening:
cat dates.txt|for j in {1..7};do echo $j; sed "s/DATE_$j/${v[$j]}/";done
You'll see the output from test.sh is the following:
1
13/03/16
DATE_2
DATE_3
DATE_4
DATE_5
DATE_6
DATE_7
2
3
4
5
6
7
Next, modify dates.txt to read:
DATE_1
DATE_2
DATE_1
DATE_4
DATE_1
DATE_6
DATE_1
, where we've turned every other line into DATE_1 for demonstration purposes. Now, the output reads:
1
13/03/16
DATE_2
13/03/16
DATE_4
13/03/16
DATE_6
13/03/16
2
3
4
5
6
7
So you see that the first iteration of the for loop (when $j == 1) is processing every line that cat is passing to the for loop. After that, the subsequent iterations of the for loop ($j == 2..7) still run, but they don't receive any input stream (so, in the above example, they just echo the current value of $j and don't pass any input to sed). That's why you were observing that it was changing only the first line.
Solution: Modify the last line to read:
for j in {1..7}; do head -$j dates.txt | tail -1 | sed "s/DATE_$j/${v[$j]}/"; done
cat dates.txt | sed 's/^DATE_//g'
This will strip DATE_ at the beginning of a line (^), leaving the number (or anything else on the line). No need for a loop at all!
I have problem that is using custom date format like date +%y%j.%H%M%S,
And what i want is to add 15 mins on the this date on just on current date of system. so that i can use for further calculation into my process.
I have tried with below code -
$uprBond=`date +%y%j.%H%M%S`
$ echo $uprBond
16079.031135
$ date -d "$(uprBond) + 5 minutes" +%y%j.%H%M%S
op > bash: uprBond: command not found
16079.035920
I am failing while passing the above date format , Can anybody please help on this.
Just for note, below is the piece of code is working when i used date function instead of defined date variable i.e. $uprBond (I don't want to use predefined date because we have some old same formatted date which needs that adding of mins).
date +%y%j.%H%M%S -d "`date` + 5 minutes";
op > 16079.040724
With GNU date, GNU bash 4 and its Parameter Expansion:
#!/bin/bash
uprBond="$(date +%y%j.%H%M%S)"
year="20${uprBond:0:2}"
doy="${uprBond#${uprBond:0:2}}"
doy="${doy%.*}"
time="${uprBond#*.}"
time="${time:0:2}:${time:2:2}:${time:4:2}"
in5min=$(date -d "${year}-01-01 +${doy} days -1 day +5 minutes ${time}" "+%y%j.%H%M%S")
echo "now: $uprBond"
echo "in 5min: $in5min"
Output:
now: 16079.145026
in 5min: 16079.145526
Tl;dr: Is there a nice way of creating a sequence of dates with 12 hour increment in the format yyyymmddHHMM in the bash?
Consider I have a python-script which accepts a certain time (yyyymmddHHMM) as input -t, i could run it like this for instance
python myscript.py -t 201411140000
which the then starts myscript.pyfor the date 2014-11-14 00:00. Now I want to run the script for many dates, beginning from 2014-01-01 00:00 to 2014-11-14 00:00 with an increment of 12 hours, i.e. i want to produce all the following lines:
python myscript.py -t 201401010000
python myscript.py -t 201401011200
python myscript.py -t 201401020000
.
.
.
python myscript.py -t 201411131200
python myscript.py -t 201411140000
The closest to what I came is (echo to verify results without running them):
for mm in {01..10}; do for dd in {01..31}; do for HH in 00 12; do echo python myscript.py -t 2014$mm$dd$HH\00; done; done; done
It produces all required dates from Jan to Oct, but also some absurd dates, such as 201402310000, which the program then has to handle (i.e. throw/log errors). That is not a huge issue, but it feels dirty.
In the end, another loop is required to handle the missing dates Nov-01 to Nov-14, which, again, seems dirty to me.
How can I create those dates more nicely - or is the way above the appropriate way of doing so?
You can convert the start date to a UNIX timestamp, and iterate over the range in 43200-second (12-hour) increments.
for ((ts=$(date +%s --date "2014-11-01 0000");
ts <= $(date +%s --date "2014-11-14 0000");
ts+=12*3600)); do
python myscript.py -t $(date +%Y%m%d%H%M --date #$ts)
done
Using the -d option:
$>for i in $(seq 0 12 72); do
date -d "+$i hours" +%Y%m%d%H%M;
done
201411141544
201411150344
201411151544
201411160344
201411161544
201411170344
201411171544
And if you want a starting date (thanks to chepner):
$> for i in $(seq 0 12 72); do
date -d "2014-11-01 0000 +$i hours" +%Y%m%d%H%M;
done
201411010000
201411011200
201411020000
201411021200
201411030000
201411031200
201411040000
Numeric addition to processed dates is bad practice - there are many edge cases and gotchas. It's just a bad plan.
Fortunately, most computers don't do that. Unix systems use 'epoch' time, which is a count of seconds since 1970.
So you can numerically add 12 hours in seconds (12 * 60 * 60).
In perl, I'd do it like this:
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
my $t = localtime();
my $num = 300;
for ( 1 .. $num ) {
$t += 12 * 60 * 60;
print $t -> strftime ( "%y%m%d%H%M" ), "\n";
}
That'll do 12 hour cycles starting from right now. Shifting to midnight is left as an exercise for the reader :).
I need to write a shell script that will create a list of 5 minutes interval times.
00-00
00-05
00-10
00-15
...
...
23-50
23-55
Here are the commands I have started with.
# date
Fri Sep 21 18:14:35 IST 2012
# date '+%H-%M'
18-14
# date '+%H-%M' --date='5 minute ago'
18-18
How do I write a script to generate the list?
If it is too complicated, I will do it manually since it is one time task.
Update:
The following script is working. But it will generate single digits like 7-5 should actually be 07-05
#!/bin/sh
for hour in `seq 0 24`
do
for minute in `seq 0 5 59`
do
echo $hour-$minute
done
done
A simple bash solution (version 4 or later):
printf "%s\n" {00..23}-{00..55..5}
If you need to start at a given date, you can use:
ITERATIONS=100 # adjust here
D=$(date +%s)
for ((i=0; i<$ITERATIONS; i++))
do
date '+%H-%M' -d #$((D+5*60*i))
done
The following shell scripting is returning the required data
#!/bin/sh
for hour in `seq -w 0 24`
do
for minute in `seq -w 0 5 59`
do
echo $hour-$minute
done
done
I need to create a bash shell script starting with a day and then loop through each subsequent day formatting that output as %Y_%m_d
I figure I can submit a start day and then another param for the number of days.
My issue/question is how to set a DATE (that is not now) and then add a day.
so my input would be 2010_04_01 6
my output would be
2010_04_01
2010_04_02
2010_04_03
2010_04_04
2010_04_05
2010_04_06
[radical#home ~]$ cat a.sh
#!/bin/bash
START=`echo $1 | tr -d _`;
for (( c=0; c<$2; c++ ))
do
echo -n "`date --date="$START +$c day" +%Y_%m_%d` ";
done
Now if you call this script with your params it will return what you wanted:
[radical#home ~]$ ./a.sh 2010_04_01 6
2010_04_01 2010_04_02 2010_04_03 2010_04_04 2010_04_05 2010_04_06
Very basic bash script should be able to do this:
#!/bin/bash
start_date=20100501
num_days=5
for i in `seq 1 $num_days`
do
date=`date +%Y/%m/%d -d "${start_date}-${i} days"`
echo $date # Use this however you want!
done
Output:
2010/04/30
2010/04/29
2010/04/28
2010/04/27
2010/04/26
Note: NONE of the solutions here will work with OS X. You would need, for example, something like this:
date -v-1d +%Y%m%d
That would print out yesterday for you. Or with underscores of course:
date -v-1d +%Y_%m_%d
So taking that into account, you should be able to adjust some of the loops in these examples with this command instead. -v option will easily allow you to add or subtract days, minutes, seconds, years, months, etc. -v+24d would add 24 days. and so on.
#!/bin/bash
inputdate="${1//_/-}" # change underscores into dashes
for ((i=0; i<$2; i++))
do
date -d "$inputdate + $i day" "+%Y_%m_%d"
done
Very basic bash script should be able to do this.
Script:
#!/bin/bash
start_date=20100501
num_days=5
for i in seq 1 $num_days
do
date=date +%Y/%m/%d -d "${start_date}-${i} days"
echo $date # Use this however you want!
done
Output:
2010/04/30
2010/04/29
2010/04/28
2010/04/27
2010/04/26
You can also use cal, for example
YYYY=2014; MM=02; for d in $(cal $MM $YYYY | grep "^ *[0-9]"); do DD=$(printf "%02d" $d); echo $YYYY$MM$DD; done
(originally posted here on my commandlinefu account)
You can pass a date via command line option -d to GNU date handling multiple input formats:
http://www.gnu.org/software/coreutils/manual/coreutils.html#Date-input-formats
Pass starting date as command line argument or use current date:
underscore_date=${1:-$(date +%y_%m_%d)}
date=${underscore_date//_/-}
for days in $(seq 0 6);do
date -d "$date + $days days" +%Y_%m_%d;
done
you can use gawk
#!/bin/bash
DATE=$1
num=$2
awk -vd="$DATE" -vn="$num" 'BEGIN{
m=split(d,D,"_")
t=mktime(D[1]" "D[2]" "D[3]" 00 00 00")
print d
for(i=1;i<=n;i++){
t+=86400
print strftime("%Y_%m_%d",t)
}
}'
output
$ ./shell.sh 2010_04_01 6
2010_04_01
2010_04_02
2010_04_03
2010_04_04
2010_04_05
2010_04_06
2010_04_07