使用awk读取串行输入,插入日期

使用awk读取串行输入,插入日期,awk,serial-port,Awk,Serial Port,我正在尝试重新格式化串行输入,它由两个用逗号分隔的整数组成(由Arduino发送): 等等,我想在每行后面加上日期,用制表符分隔所有内容。以下是我目前的代码: cat /dev/cu.usbmodem3d11 | awk 'BEGIN {RS=","};{printf "%i\t%i\t%s",$1,$2,system("date")}' 以下是我得到的结果(日期在我的区域设置中): 为什么在我的日期字段前面有一个额外的“0”?很抱歉问你这个新手问题:( 编辑此代码解决了我的问题。感谢所有帮助

我正在尝试重新格式化串行输入,它由两个用逗号分隔的整数组成(由Arduino发送):

等等,我想在每行后面加上日期,用制表符分隔所有内容。以下是我目前的代码:

cat /dev/cu.usbmodem3d11 | awk 'BEGIN {RS=","};{printf "%i\t%i\t%s",$1,$2,system("date")}'
以下是我得到的结果(日期在我的区域设置中):

为什么在我的日期字段前面有一个额外的“0”?很抱歉问你这个新手问题:(

编辑此代码解决了我的问题。感谢所有帮助我的人

awk 'BEGIN {FS=","};{system("date")|getline myDate;printf "%i\t%i\t%s",$1, $2, myDate}' /dev/cu.usbmodem3d11
我不清楚为什么,但为了让日期不断更新和记录数据接收的时间,我必须使用
系统(“日期”)
,而不是上面代码中的
“日期”

2件事

如果在
printf
字符串的末尾添加
\n
,则更容易看到问题

然后输出为

>echo '1,2' | awk 'BEGIN {RS=","};{printf "%i\t%i\t%s\n",$1,$2,system("date")}'
Wed Feb 26 21:30:17 CST 2014
1       0       0
Wed Feb 26 21:30:17 CST 2014
2       0       0
> echo '1,2' | awk 'BEGIN {RS=","};{"date" | getline myDt ; printf "%i\t%i\t%s\n",$1,$2,myDt}'
1       0       Wed Feb 26 21:31:15 CST 2014

2       0       Wed Feb 26 21:31:15 CST 2014
我猜
系统(“日期”)
的输出返回的输出“超出”了awk处理的每行输入的
$0
自然范围。其他人可能能够提供更好的解释

为了获得所需的输出,我使用
getline
函数将
date
命令的输出捕获到一个变量(
myDt

>echo '1,2' | awk 'BEGIN {RS=","};{printf "%i\t%i\t%s\n",$1,$2,system("date")}'
Wed Feb 26 21:30:17 CST 2014
1       0       0
Wed Feb 26 21:30:17 CST 2014
2       0       0
> echo '1,2' | awk 'BEGIN {RS=","};{"date" | getline myDt ; printf "%i\t%i\t%s\n",$1,$2,myDt}'
1       0       Wed Feb 26 21:31:15 CST 2014

2       0       Wed Feb 26 21:31:15 CST 2014
最后,我们删除“调试”
\n
字符,并获得您指定的输出:

> echo '1,2' | awk 'BEGIN {RS=","};{"date" | getline myDt ; printf "%i\t%i\t%s",$1,$2,myDt}'
1       0       Wed Feb 26 21:34:56 CST 2014
2       0       Wed Feb 26 21:34:56 CST 2014
而且,根据Jaypal的帖子,我现在看到
FS=“,”
是另一个问题,所以当我们进行更改并返回“\n”字符时,我们有

echo '1,2' | awk 'BEGIN {FS=","};{"date" | getline myDt ; printf "%i\t%i\t%s\n",$1,$2,myDt}'
1       2       Wed Feb 26 21:44:42 CST 2014

两个问题:

First-
RS
是记录分隔符。您需要
FS
作为字段分隔符来分隔两列,其中
$1
将是
1
$2
将是
2
(根据您的第一行)

Second-您在输出中看到的额外的
0
system()
命令的返回值。这意味着它运行成功。您只需在引号中运行shell命令并将其传递到
getline
。在它之后放置一个变量将允许您捕获返回的值

试试这个:

 awk 'BEGIN {FS=","};{"date"|getline var;printf "%i\t%i\t%s\n",$1,$2,var}'

这是一个更简单的解决方案:

awk -F, '{print $1,$2,dt}' dt="$(date)" OFS="\t" /dev/cu.usbmodem3d11
1       2       Thu Feb 27 06:23:41 CET 2014
3       4       Thu Feb 27 06:23:41 CET 2014
0       0       Thu Feb 27 06:23:41 CET 2014
0       1       Thu Feb 27 06:23:41 CET 2014
如果您想以另一种格式显示日期,只需阅读
date


Eks
dt=“$(date+%D)”
给出了
02/27/14

您应该尽量避免将
cat
与可以读取文件本身的程序一起使用,比如
awk
。Eks
awk'code'/dev/cu.usbmodem3d11
使用awk有什么特别的原因吗?在纯shell(bash或posix)中可以很容易地做到这一点不需要调用其他语言解释器。@Jotne good point将相应地更新。当awk首次运行时,这不是只运行一次
date
命令吗?如果在
tail-f
上运行,日期将永远不会更改。感谢您的帮助。但是,日期也不会使用此代码递增(请参阅用户gothi对其他解决方案的其他评论)。我的猜测是“date”| getline命令只执行一次。为了澄清,我需要日期来反映读取数据的时间(从串行端口传输)。按原样使用代码,日期永远不会更新。使用
system(“日期”)| getline myDt
相反,日期被更新。我希望
是“日期”|getline myDt
来处理读取的每一行数据。我现在没有时间测试它。您让它运行了一段时间吗?您仍然得到相同的日期吗?如果是,那么感谢您的共享!在任何情况下,我都很高兴能提供帮助。祝大家好运。在这里,相同的日期不会增加。按原样使用代码,日期永远不会更新通过使用
system(“date”)| getline var
更新日期。