在 CSV 檔案中將日期格式從 MM/DD/YYYY HH:MM:SS am/pm 變更為 YYYY-MM-DD HH:MM:SS

在 CSV 檔案中將日期格式從 MM/DD/YYYY HH:MM:SS am/pm 變更為 YYYY-MM-DD HH:MM:SS

我試圖隱藏從供應商那裡獲得的 csv 檔案的日期格式,以便我可以將資料上傳到我的 Google Bigquery。我正在使用 Google Cloud Console 中的虛擬機器。

數據看起來像這樣:

Name ,Phone ,SalesDate ,Venue ,NoOfUnits ,ModifiedDatae

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

我試著將其做成以下格式:

Name ,Phone ,SalesDate ,Venue ,NoOfUnits ,ModifiedDatae

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

我知道我可以使用 sed 或 awk。

答案1

我編寫了一個 Python 腳本和一個 Bash 腳本,應該可以完成您想要的操作。

Python是解決方案

以下是一個 Python 腳本,可將所有時間欄位從一種格式轉換為另一種格式,如問題中所指定:

#!/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))

假設您的 CSV 檔案被呼叫data.csv並包含以下行(摘自您的貼文):

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

然後你可以像這樣運行腳本:

python reformat_time.py data.csv

這將產生以下輸出:

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

重擊解決方案

這是一個使用 GNUdate實用程式的 Bash 腳本,它具有(幾乎)相同的效果:

#!/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"

你可以這樣運行它:

bash reformat_time.sh data.csv

它會產生以下輸出:

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

請注意,Bash 腳本要脆弱得多。它不進行錯誤處理,僅影響第三和第六字段。它還保留了字段分隔符號周圍的空白,而上面的 Python 腳本則沒有。

答案2

我是 Linux 新手,我正在嘗試隱藏日期格式

嘗試使用date開關-d

       -d, --date=字串
              顯示 STRING 描述的時間,而不是“現在”

然後按照您想要的方式格式化輸出。

例子:

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

有關格式化的說明,請參閱man date(參考資料FORMAT部分)。

答案3

你可以嘗試用這個 awk

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

答案4

另一種可能的 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

相關內容