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

I S*_*ngh 5 command-line text-processing

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

2016-01-01, AAA, 330, 1430

2016-01-02, ABA, 130, 930
Run Code Online (Sandbox Code Playgroud)

我需要这样的输出:

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
Run Code Online (Sandbox Code Playgroud)

如何才能做到这一点?

Byt*_*der 9

可以使用如下简单的字符串替换来完成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
Run Code Online (Sandbox Code Playgroud)

或者将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
}
Run Code Online (Sandbox Code Playgroud)

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

  • 第一列(日期),逗号,第二列(desc),逗号,
  • 第一列(日期)、第三列值 / 100(时间戳 1 的小时数)、冒号、第三列值模 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
Run Code Online (Sandbox Code Playgroud)


Lie*_*tok 6

您可以使用它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
Run Code Online (Sandbox Code Playgroud)

它的作用如下:

  • -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从指定文件读取s 输入。
  • > output.txt告诉 shell 将awks 输出写入该文件。