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)
如何才能做到这一点?
可以使用如下简单的字符串替换来完成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,指定的格式打印出相应的列值(输入以逗号分隔):
有问题的输入数据的结果将是
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)
您可以使用它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 输出写入该文件。