简体   繁体   中英

Convert a date with bash into mysql format

I'm front this situation :

foo.csv

blabla;01/01/2014;13:03:11;01/02/2014;14:16:58

So the two first fields correspond to the date of start : 01/01/2014;13:03:11

The two last fields correspond to the date of end : 01/02/2014;14:16:58

Finally I desire to obtain :

blabla;2014-01-01 13:03:11;2014-02-01 14:16:58

Someone have an idea of what to use to get there ?

line="blabla;01/01/2014;13:03:11;01/02/2014;14:16:58"
OLD_IFS="$IFS"           # Save old value of $IFS
IFS=";"
read blah start_date start_time end_date end_time <<<$line
IFS="/"
read month day year <<<$start_date
start_date="$year-$month-$day
read month day year <<<$end_date
end_date="$year-$month-$day"
IFS="$OLD_IFS"
echo "$blah;$start_date;$start_time;$end_date;$end_time"

The $IFS stands for Input File Separator. It's used in read statements to figure out the breaks in inputs. It normally defaults to space, tab Newline, but you can change it.

I first set it to ; , so I can divide up your semi-colon separated input. Once I have $start_date and $end_date , I set IFS to / which is my separator for the date string. I then reformat my dates, and reset IFS to its original value.

You can use awk for such formatting:

$ awk '
BEGIN {FS = OFS = ";" }
{
    split($2, d, /\//)
    $2 = d[3]"-"d[2]"-"d[1]" "$3
    split($4, d, /\//)
    $3 = d[3]"-"d[2]"-"d[1]" "$5
    $0 = $1 FS $2 FS $3
}1' file
blabla;2014-01-01 13:03:11;2014-02-01 14:16:58

Explanation:

  • We set the input and out field separator to ;
  • split function splits the second field which is a date in to an array so that we can re-organize it. We pad the next field which is time to this field.
  • We perform similar operation on the next date.
  • We re-structure our entire line to carry new three fields.
  • 1 allows us to print the new formatted line.

If you have no problem to use the Perl oneliner then try this one:

cat input.txt | perl -lne '($a,$b,$c,$d,$e) = /^([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)$/g; $b =~ s|(\d\d?)/(\d\d?)/(\d{4})|$3-$2-$1|g; $d =~ s|(\d\d?)/(\d\d?)/(\d{4})|$3-$2-$1|g; print "$a;$b $c;$d $e";'

or pushing directly the input file(see at the end of the command) to the Perl

perl -lne '($a,$b,$c,$d,$e) = /^([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)$/g; $b =~ s|(\d\d?)/(\d\d?)/(\d{4})|$3-$2-$1|g; $d =~ s|(\d\d?)/(\d\d?)/(\d{4})|$3-$2-$1|g; print "$a;$b $c;$d $e";' input.txt

This is basically combination of several lines of Perl code separated by ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM