Read serial input with awk, insert date

不羁岁月 提交于 2019-12-23 21:31:13

问题


I'm trying to reformat serial input, which consists of two integers separated by a comma (sent from an Arduino):

1,2
3,4
0,0
0,1

etc. I would like to append the date after each line, separating everything with a tab character. Here's my code so far:

cat /dev/cu.usbmodem3d11 | awk 'BEGIN {RS=","};{printf "%i\t%i\t%s",$1,$2,system("date")}'

Here's the result I get (with date in my locale):

1   2   0Mer 26 fév 2014 22:09:20 EST
3   4   0Mer 26 fév 2014 22:09:20 EST
0   0   0Mer 26 fév 2014 22:09:20 EST
0   1   0Mer 26 fév 2014 22:09:20 EST

Why is there an extra '0' in front of my date field? Sorry for the newbie question :(

EDIT This code solved my problem. Thanks to all who helped.

awk 'BEGIN {FS=","};{system("date")|getline myDate;printf "%i\t%i\t%s",$1, $2, myDate}' /dev/cu.usbmodem3d11

I'm not clear why, but in order for the date to keep updating and recording at what time the data was received, I have to use system("date")instead of just "date"in the code above.


回答1:


2 things

It will be easier to see your problem if you add a \n at the end of your printf string

Then the output is

>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

I'm guessing that output from system("date") returns its output "outside" of scope of awk's $0 natural scope of each line of input processed. Others may be able to offer a better explanation.

To get the output you want, I'm using the getline function to capture the output of the date command to a variable (myDt). Now the output is

> 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

Finally, we remove the "debugging" \n char, and get the output you specify:

> 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

And, per Jaypal's post, I see now that FS="," is another issue, so when we make that change AND return the `\n' char, we have

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



回答2:


Two issues:

First - RS is record separator. You need FS which is Field Separator to separate two columns, where $1 will be 1 and $2 will be 2 (as per your first row)

Second - The extra 0 you see in output is the return value of system() command. It means it ran successfully. You can simply run the shell command in quotes and pipe it to getline. Putting a variable after it will allow you to capture the value returned.

Try this:

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



回答3:


This is a more simple solution:

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

IF you like to show date in another format, just read manual for date
Eks dt="$(date +%D)" gives 02/27/14



来源:https://stackoverflow.com/questions/22058379/read-serial-input-with-awk-insert-date

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!