Ändern Sie das Datumsformat von MM/TT/JJJJ HH:MM:SS am/pm in JJJJ-MM-TT HH:MM:SS in einer CSV-Datei

Ändern Sie das Datumsformat von MM/TT/JJJJ HH:MM:SS am/pm in JJJJ-MM-TT HH:MM:SS in einer CSV-Datei

Ich versuche, das Datumsformat für diese CSV-Datei, die ich vom Anbieter erhalten habe, zu konvertieren, damit ich die Daten in meine Google BigQuery hochladen kann. Ich verwende eine VM aus der Google Cloud Console.

Die Daten sehen ungefähr so ​​aus:

Name ,Phone ,SalesDate ,Venue ,NoOfUnits ,ModifiedDatae

Victor ,5555555 ,12/6/2013 10:26:32 AM , Colosseum ,1 ,12/8/2013 1:05:45 PM

Ich versuche, es im folgenden Format zu erstellen:

Name ,Phone ,SalesDate ,Venue ,NoOfUnits ,ModifiedDatae

Victor ,5555555 ,2013-12-6 10:26:32 ,Colosseum,1 ,2013-12-8 13:05:45

Ich weiß, dass ich sed oder awk verwenden kann.

Antwort1

Ich habe ein Python-Skript und ein Bash-Skript geschrieben, die das Gewünschte tun sollten.

Python-Lösung

Hier ist ein Python-Skript, das alle Zeitfelder von einem Format in ein anderes konvertiert, wie in der Frage angegeben:

#!/usr/bin/env python3
# -*- coding: ascii -*-
"""reformat_time.py

Change date format from:

    MM/DD/YYYY HH:MM:SS am/pm

to:

    YYYY-MM-DD HH:MM:SS

in a CSV file
"""

import csv
from datetime import date
from datetime import datetime
import sys

# Open the file (taken as a command-line argument)
with open(sys.argv[1], 'r') as csvfile:

    # Parse the CSV data
    csvreader = csv.reader(csvfile, delimiter=',', quotechar='"')

    # Iterate over the rows
    for row in csvreader:

        # Iterate over the columns of each row
        for index, col in enumerate(row):

            # Try to parse and convert each column
            try:
                _datetime = datetime.strptime(col, "%m/%d/%Y %H:%M:%S %p")
                newcol = _datetime.strftime("%Y-%m-%d %H:%M:%S")

            # If parsing fails, leave the column unchanged
            except ValueError:
                newcol = col

            # Update the column value
            row[index] = newcol

        # Output the updated row
        print(','.join(row))

Angenommen, Ihre CSV-Datei heißt data.csvund enthält die folgende Zeile (aus Ihrem Beitrag entnommen):

Victor,5555555,12/6/2013 10:26:32 AM,Colosseum,1,12/8/2013 1:05:45 PM

Anschließend könnten Sie das Skript folgendermaßen ausführen:

python reformat_time.py data.csv

Dies würde die folgende Ausgabe erzeugen:

Victor,5555555,2013-12-06 10:26:32,Colosseum,1,2013-12-08 01:05:45

Bash-Lösung

Und hier ist ein Bash-Skript, das das GNU- dateDienstprogramm verwendet und (fast) den gleichen Effekt hat:

#!/bin/bash
# reformat_time.sh

# Loop over the lines of the file
while read -r line; do

    # Extract the field values for each row
    Name="$(echo ${line} | cut -d, -f1)";
    Phone="$(echo ${line} | cut -d, -f2)";
    SalesDate="$(echo ${line} | cut -d, -f3)";
    Venue="$(echo ${line} | cut -d, -f4)";
    NoOfUnits="$(echo ${line} | cut -d, -f5)";
    ModifiedDate="$(echo ${line} | cut -d, -f6)";

    # Convert the time-fields from the old format to the new format
    NewSalesDate="$(date -d "${SalesDate}" "+%Y-%m-%d %H:%M:%S")";
    NewModifiedDate="$(date -d "${ModifiedDate}" "+%Y-%m-%d %H:%M:%S")";

    # Output the updated row
    echo "${Name},${Phone},${NewSalesDate},${Venue},${NoOfUnits},${NewModifiedDate}";

done < "$1"

Sie könnten es folgendermaßen ausführen:

bash reformat_time.sh data.csv

Und es würde die folgende Ausgabe erzeugen:

Victor ,5555555 ,2013-12-06 10:26:32, Colosseum ,1 ,2013-12-08 13:05:45

Beachten Sie, dass das Bash-Skript viel anfälliger ist. Es führt keine Fehlerbehandlung durch und betrifft nur das 3. und 6. Feld. Es behält auch das Leerzeichen um den Feldtrenner bei, was beim obigen Python-Skript nicht der Fall ist.

Antwort2

Ich bin neu bei Linux und versuche, das Datumsformat umzuwandeln

Versuchen Sie es datemit dem -dSchalter:

       -d, --date=ZEICHENKETTE
              Anzeigezeit durch STRING beschrieben, nicht „jetzt“

Und formatieren Sie die Ausgabe dann nach Ihren Wünschen.

Beispiel:

date -d "12/6/2013 10:26:32 AM" "+%F %H:%M:%S"
2013-12-06 10:26:32

Eine Erläuterung der Formatierung finden Sie unter man date( FORMATAbschnitt).

Antwort3

Sie können es mit diesem awk versuchen

awk -F, '
function cvtdate( dat,  array) {
    split(dat,array,"/| |:")
    array[4]=array[7]=="PM"?(array[4]+12):array[4]
    return array[3]"-"array[1]"-"array[2]" "array[4]":"array[5]":"array[6]
}
{
    $3=cvtdate($3)
    $6=cvtdate($6)
}1' OFS=',' infile

Antwort4

Ein weiterer möglicher Awk-Oneliner:

awk -F, '{ a[3];a[6] ; for (i in a) "date -d \""$i"\" \"+%Y-%m-%d %H:%M:%S\"" |& getline $i }1' OFS=, filename

verwandte Informationen