TheLazyFox
TheLazyFox

Reputation: 1065

Grep dates from file and format them

I have a file "tmp.txt" looking like that:

random text random text 25/06/2021 15:15:15
random text random text 26/06/2021 15:15:15
random text random text 26/06/2021 15:15:15

and I would like to:

  1. extract all datetimes
  2. add 4 hours
  3. display them as timestamp

I didn't figured out yet how to add hour as I,m facing an issue with the date format not being recognized by the date function.

(I would like to be able to do it with a single line command if possible)

Here is my current command:

egrep -o "[0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}" tmp.txt | while read -r line ; do echo $(date -d  "$line" +%s);done

Help appreciated!

Upvotes: 3

Views: 4628

Answers (2)

Pavan
Pavan

Reputation: 662

Tried and Tested, Minimal Solution

You can use the below command line to get the desired result. I have tested it with your example and it worked as expected on my Linux machine.

egrep -o "[0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}" tmp.txt | while read -r line; do dd=${line:0:2}; mm=${line:3:2}; yyyy=${line:6:4}; time=${line:11:8}; date -d "${yyyy}-${mm}-${dd} ${time} 4 hours" +'%Y-%m-%d %H:%M:%S'; done

I'll break it down into multiple lines so it's easy to understand:

egrep -o "[0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}" tmp.txt \
| \
while read -r line; do
# Reading date and time into separate variables
dd=${line:0:2};
mm=${line:3:2};
yyyy=${line:6:4};
time=${line:11:8};
# Adding 4 hours and displaying datetime in desired format
date -d "${yyyy}-${mm}-${dd} ${time} 4 hours" +'%Y-%m-%d %H:%M:%S';
done

To add 4 hours, you can just mention it after the datetime in -d option as shown above, I tried with hours, minute and days and it worked as expected

For your input file tmp.txt:

random text random text 25/06/2021 15:15:15
random text random text 26/06/2021 15:15:15
random text random text 26/06/2021 15:15:15

On running my command, the output was:

2021-06-25 19:15:15
2021-06-26 19:15:15
2021-06-26 19:15:15

I tested it with edge cases like close to midnight time, leap years etc and it worked fine

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 246799

Let me adjust the timestamps to make the output more interesting:

$ cat tmp.txt
random text random text 25/06/2021 15:15:15
random text random text 26/06/2021 20:15:15
random text random text 26/06/2021 23:15:15

@jhnc has the right idea: use a language that's both good at text manipulation and can do date arithmetic. I'd use Time::Piece

perl -MTime::Piece -lne '
    m{(\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)} or continue;
    $t = Time::Piece->strptime($1, "%d/%m/%Y %T");
    $t += 4 * 3600;
    print $t->strftime("%F %T")
' tmp.txt
2021-06-25 19:15:15
2021-06-27 00:15:15
2021-06-27 03:15:15

Or, here's perl piping into xargs for the date stuff

perl -pe 's{.*(\d{2})/(\d{2})/(\d{4}) (\d{2}:\d{2}:\d{2}).*}
           {$2/$1/$3 +4 hours $4}
' tmp.txt | xargs -I DT date -d DT '+%F %T'
2021-06-25 19:15:15
2021-06-27 00:15:15
2021-06-27 03:15:15

Upvotes: 0

Related Questions