我试图隐藏从供应商那里获得的 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