Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用awk格式化和替换时间戳列_Bash_Shell_Unix_Awk - Fatal编程技术网

Bash 使用awk格式化和替换时间戳列

Bash 使用awk格式化和替换时间戳列,bash,shell,unix,awk,Bash,Shell,Unix,Awk,我有以下格式的多个列 D,"4/2/2017 2:45:56 PM",ee,"4/2/2017 2:45:56 PM" D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM" D,"09/2/2017 6:05:54 AM",ee,"09/2/2017 6:05:54 AM" D,"5/01/2017 8:29:46 PM",ee,"5/01/2017 8:29:46 PM" D,"4/2/2017 02:3:26 AM",ee,"4/2/2

我有以下格式的多个列

D,"4/2/2017 2:45:56 PM",ee,"4/2/2017 2:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/2/2017 6:05:54 AM",ee,"09/2/2017 6:05:54 AM"
D,"5/01/2017 8:29:46 PM",ee,"5/01/2017 8:29:46 PM"
D,"4/2/2017 02:3:26 AM",ee,"4/2/2017 02:3:26 AM"
我想把它们格式化如下

D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM"
D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM"
D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM"
D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM"
D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM"
D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM"
我尝试使用awk-F[,/:]分离列,然后根据长度进行处理

但是当有多个列时,它就变得单调乏味了

请建议awk中是否有任何日期时间或时间戳格式选项,以便我可以快速处理列式格式

我建议使用awk及其printf格式化输出:

awk -F '["/ :]' '{printf "%s\"%.2d/%.2d/%d %.2d:%.2d:%.2d %s\"%s\"%.2d/%.2d/%d %.2d:%.2d:%.2d %s\"\n",$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16}' file
输出:

D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM" D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM" D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM" D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM" D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM" 使用GNU awk与seps拆分。代码:

输出:

D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM" D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM" D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM" D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM" D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM" 您也可以使用sed,将字边界到pad之间的所有单个数字替换为0。但它会改变数据中的任何一个数字,即使它不在日期列中。因此,仅当您希望替换所有单次出现的附加0的数字时才使用它

如果要使更改永久化,请将-i与sed一起使用

它是如何工作的

正则表达式\b\[:digit:][\\b将匹配单词边界之间的单个数字,并用大括号捕获。现在,在sed的“替换”部分中,用第一个匹配的模式对0进行硬编码\1将得到0,并用单个数字填充

正则表达式演示

要了解此正则表达式的工作原理,请参见

工作示例:


我更喜欢这种方法,因为它也适用于mawk——基于Debian的发行版中的默认awk。我曾尝试使用gensub,但放弃了,因为它在mawk中不可用。@EdMorton我的版本是Ubuntu16.04附带的1.3.3-17。这与最近的Ubuntu17.04和即将发布的Debian9是同一个版本。在他们的网页中,他们声明:正如前面提到的,mawk被一些包装商忽略了。我真的不明白为什么Debian选择mawk作为默认awk,甚至不想使用最新版本。我可以理解/bin/sh的选择不是/bin/bash,但不是这个。出现错误。。4是Split的无效参数,是GNU awk的,先生。我相信你在评论中提到了mawk,两者都好。
D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM"
D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM"
D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM"
$ cat tst.awk
function fmt(t,    f) {
    split(t,f,/["\/ :]/)
    return sprintf("\"%02d/%02d/%04d %02d:%02d:%02d %s\"",f[2],f[3],f[4],f[5],f[6],f[7],f[8])
}
BEGIN { FS=OFS="," }
{ $2=fmt($2); $4=fmt($4); print }

$ awk -f tst.awk file
D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM"
D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM"
D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM"
sed 's|\b\([[:digit:]]\)\b|0\1|g'
bash-4.2$ cat file1
D,"4/2/2017 2:45:56 PM",ee,"4/2/2017 2:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/2/2017 6:05:54 AM",ee,"09/2/2017 6:05:54 AM"
D,"5/01/2017 8:29:46 PM",ee,"5/01/2017 8:29:46 PM"
D,"4/2/2017 02:3:26 AM",ee,"4/2/2017 02:3:26 AM"

bash-4.2$ sed -i 's|\b\([[:digit:]]\)\b|0\1|g' file1

bash-4.2$ cat file1
D,"04/02/2017 02:45:56 PM",ee,"04/02/2017 02:45:56 PM"
D,"03/02/2017 03:47:16 PM",ee,"03/02/2017 03:47:16 PM"
D,"09/02/2017 06:05:54 AM",ee,"09/02/2017 06:05:54 AM"
D,"05/01/2017 08:29:46 PM",ee,"05/01/2017 08:29:46 PM"
D,"04/02/2017 02:03:26 AM",ee,"04/02/2017 02:03:26 AM"