【问题标题】:How to change date format of data for each line in Unix?如何更改 Unix 中每一行数据的日期格式?
【发布时间】:2016-04-11 22:00:27
【问题描述】:

我正在自动化一些以 .csv 格式生成的数据,但在使用数据值格式化字段时我被卡住了。请帮我解决这个问题。

我在 .csv 文件中有以下数据:

April 3 2016    FL  03112017    0
April 4 2016    CA  04022016    0 
April 5 2016    TX  04302016    0 
April 6 2016    OH  05292016    0 
April 7 2016    AZ  06092016    0 
April 8 2016    MA  06252016    0

我想创建如下文件:

2016-04-03  FL  03112017    0
2016-04-04  CA  04022016    0
2016-04-05  TX  04302016    0
2016-04-06  OH  05292016    0
2016-04-07  AZ  06092016    0
2016-04-08  MA  06252016    0

我已经使用 awk 尝试过,类似这样:

awk -F "\t" '{print "date -d "$1" +'%Y-%m-%d'",$2,$3}' file.csv > file1.txt

这行不通。我无法将结果/计算值分配给必须打印的 $1。

【问题讨论】:

  • Converting dates in AWK的可能重复
  • 不,这不是重复的,因为此示例输入包含年份。此外,在该问题中选择的答案不是很好,因为其中的第一个脚本不必要地产生了一个子shell,并为文件中的每一行调用一个 shell 工具,而它所要做的就是计算出一年,然后在什么时候打印它改组每一行的文本,第二个答案错误地使用getline(没有测试/保护失败)。

标签: shell unix awk


【解决方案1】:

不需要日期函数,只需对文本进行洗牌:

$ awk '
     BEGIN{m="JanFebMarAprMayJunJulAugSepOctNovDec"}
     {printf "%04d-%02d-%02d %s %s %s\n",$3,(match(m,substr($1,1,3))+2)/3,$2,$4,$5,$6}
  ' file
2016-04-03 FL 03112017 0
2016-04-04 CA 04022016 0
2016-04-05 TX 04302016 0
2016-04-06 OH 05292016 0
2016-04-07 AZ 06092016 0
2016-04-08 MA 06252016 0

【讨论】:

  • 感谢@Ed Morton。这行得通。您能否告诉我是否可以在“awk”命令中使用日期格式(使用我提到的代码中的日期命令)?这将帮助我完成我需要做的其他操作。
  • 不客气。是的,你可以,但如果你有 GNU awk,那么你就不必因为gawk has it's own time functions。通过使用-d 选项判断您正在使用 GNU 日期,因此您也应该使用 GNU awk。
  • 嘿,这段代码很有用,但我在使用它时遇到了一些问题。输入文件是制表符分隔的,输出文件也必须是制表符分隔的。我尝试了不同的代码变体来生成一个制表符分隔的文件,但我做不到。你能帮我解决这个问题吗?
  • 要修改输出间距,只需将 printf 格式化字符串中的空白字符更改为 \ts:printf "%04d-%02d-%02d\t%s\t%s\t%s\n"。您的输入是制表符分隔的这一事实无关紧要,因为您的输入字段中没有空字段或空白字符。
  • @Jonathan 您可以使用pastedate 命令进行进程替换,如果您有多种date 格式需要考虑,这可能比awk 更好:@ 987654330@
【解决方案2】:

在这里,我使用date 来生成月份名称:并非绝对必要。

awk -v monthNames="$(for m in $(seq 1 12); do date -d "$m/1" +%B; done | paste -sd,)" '
    BEGIN {
        split(monthNames, mn, ",")
        for (i=1; i<=12; i++) m[mn[i]] = i
        delete mn
        FS = OFS = "\t"
    }
    {
        split($1, d, " ")
        $1 = sprintf("%d-%02d-%02d", d[3], m[d[1]], d[2])
        print
    }
' file.csv

【讨论】:

    猜你喜欢
    • 2015-04-15
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多