
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.csv
und 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- date
Dienstprogramm 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 date
mit dem -d
Schalter:
-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
( FORMAT
Abschnitt).
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