需要连接日期和整数来获取日期时间值

需要连接日期和整数来获取日期时间值

我有一个像这样的输入数据文件,其中的列名不包含在数据文件中(Date,,,):DescTimestamp1Timestamp2

2016-01-01, AAA, 330, 1430

2016-01-02, ABA, 130, 930

我需要这样的输出:

2016-01-01, AAA, 2016-01-01 03:30, 2016-01-01 14:30

2016-01-02, ABA, 2016-01-02 01:30, 2016-01-02 09:30

如何才能做到这一点?

答案1

它可以像下面使用一样通过简单的字符串替换来完成awk,但请注意,如果格式稍有变化或输入数据无效,则此方法可能不太可靠。

awk -F, '/,/{printf "%s, %s, %s %02d:%02d, %s %02d:%02d\n",$1,$2,$1,int($3/100),$3%100,$1,int($4/100),$4%100}' YOUR_FILE.CSV

或者对awk代码进行格式化以提高可读性:

/,/ {
    printf "%s, %s, %s %02d:%02d, %s %02d:%02d\n",
           $1, $2, 
           $1, int($3 / 100), $3 % 100,
           $1, int($4 / 100), $4 % 100
}

用简单的英语来说,这将在包含逗号的每一行上运行(以避免处理空行)并仅-F,使用指定的格式打印出相应的列值(由于输入以逗号分隔):

  • 第一列(日期),逗号,第二列(降序),逗号,
  • 第 1 列(日期)、第 3 列值 / 100(时间戳 1 的小时)、冒号、第 3 列值模 100(时间戳 1 的分钟)、逗号
  • 第 1 列(日期)、第 4 列值 / 100(时间戳 2 的小时数)、冒号、第 4 列值模 100(时间戳 2 的分钟数)

您输入的数据的结果将是

2016-01-01,  AAA, 2016-01-01 03:30, 2016-01-01 14:30
2016-01-02,  ABA, 2016-01-02 01:30, 2016-01-02 09:30

答案2

您可以使用awk来实现所需的输出。我不确定输入和输出之间的空白行是否真的存在或只是格式问题,但我在命令中考虑了它们。

awk -F, '{if (NF) { print $1 "," $2 ", " $1 " " sprintf("%02d", int($3 / 100)) ":" $3 % 100 ", " $1 " " sprintf("%02d", int($4 / 100)) ":" $4 % 100 } else { print }}' < input.txt > output.txt

其作用如下:

  • -F,将输入字段分隔符设置为awk,以便正确拆分输入。
  • if (NF)检查输入字段的数量是否大于零。这是为了处理空行。如果该行是空的,则else命令末尾的部分将打印一个空行。
  • print命令打印指定的字段:
    • $1是输入的第一个字段,即日期
    • ","打印文字逗号
    • $2是第二个字段,描述
    • ", "打印下一个逗号
    • $1再次打印日期作为时间戳
    • " "在日期和时间之间添加空格
    • sprintf("%02d", int($3 / 100))首先通过将时间除以 100 来计算时间的小时部分,丢弃小数(int()这样做)并打印带有前导零的两位数字(%02d%作为sprintf()处理的格式字符串)
    • ":"又是一个冒号
    • $3 % 100是取模运算,将时间除以 100 得到余数,从而得到分钟数
    • ", " $1 " " sprintf("%02d", int($4 / 100)) ":" $4 % 100第二个时间戳也一样
  • else部分内容已在上面用 进行了说明if
  • < input.txt告诉 shellawk从指定文件读取输入。
  • > output.txt告诉 shell 将awk输出写入该文件。

答案3

这是一个 perl 变体(其s/pattern/replacement/具有e允许在替换中评估表达式的修饰符):

perl -F', ' -lpe '$_ = join ",", @F[0,1], map { 
    s/(\d?\d)(\d\d)/sprintf "%s %02d:%02d", $F[0], $1, $2/e ; $_ 
  } @F[2,3] if @F
' file
2016-01-01, AAA, 2016-01-01 03:30, 2016-01-01 14:30

2016-01-02, ABA, 2016-01-02 01:30, 2016-01-02 09:30

答案4

遵循 Perl 版本,采用获取基本元素并重新格式化的策略

perl -ne '/((.*?),.*?, )(\d*)(\d\d), (\d*)(\d\d)/ and 
            printf("%s%s %02d:%s, %s %02d:%s\n", $1,$2,$3,$4,$2,$5,$6)'

相关内容