awk 命令 while ((getline < "gpsoutput.tr") > 0 用于不断更新文件内容

awk 命令 while ((getline < "gpsoutput.tr") > 0 用于不断更新文件内容

我目前正在使用 G-STAR IV globalsat GPS,它为我提供以下输出(每秒从 GPS 发出一次),我通过重定向到文件名“gpsoutput.tr”来保存此输出。每次收到 GPS 信号时,此文件都会不断更新。此文件的内容如下:

$GPGSV,3,2,10,14,43,184,,27,33,314,,29,21,152,,16,17,263,*7D
$GPGSV,3,3,10,24,10,092,,19,06,322,*79
$GPRMC,095827.000,A,2335.2440,N,05809.8432,E,0.55,103.38,091114,,,A*66
$GPGGA,095828.000,2335.2443,N,05809.8433,E,1,04,5.2,89.5,M,-34.7,M,,0000*46
$GPGSA,A,3,21,22,18,15,,,,,,,,,6.4,5.2,3.6*3C
$GPRMC,095828.000,A,2335.2443,N,05809.8433,E,1.21,102.44,091114,,,A*63
$GPGGA,095829.000,2335.2446,N,05809.8434,E,1,04,5.2,89.5,M,-34.7,M,,0000*45
$GPGSA,A,3,21,22,18,15,,,,,,,,,6.4,5.2,3.6*3C
$GPRMC,095829.000,A,2335.2446,N,05809.8434,E,0.92,102.44,091114,,,A*69
$GPGGA,095830.000,2335.2448,N,05809.8437,E,1,04,5.2,89.5,M,-34.7,M,,0000*40
$GPGSA,A,3,21,22,18,15,,,,,,,,,6.4,5.2,3.6*3C
$GPRMC,095830.000,A,2335.2448,N,05809.8437,E,1.25,102.12,091114,,,A*62
$GPGGA,095831.000,2335.2450,N,05809.8441,E,1,04,5.2,89.5,M,-34.7,M,,0000*49
$GPGSA,A,3,21,22,18,15,,,,,,,,,6.4,5.2,3.6*3C
$GPRMC,095831.000,A,2335.2450,N,05809.8441,E,1.47,101.80,091114,,,A*67
$GPGGA,095832.000,2335.2455,N,05809.8446,E,1,04,5.2,89.5,M,-34.7,M,,0000*48
$GPGSA,A,3,21,22,18,15,,,,,,,,,6.4,5.2,3.6*3C
$GPGSV,3,1,10,21,55,052,18,22,54,297,14,18,53,011,22,15,18,042,18*72
$GPGSV,3,2,10,14,43,184,,27,33,314,,29,21,152,,16,17,263,*7D
$GPGSV,3,3,10,24,10,092,,19,06,322,*79
$GPRMC,095832.000,A,2335.2455,N,05809.8446,E,2.36,100.07,091114,,,A*6D

每次接收到 GPS 信号时,此文件(“gpsoutput.tr”)就会不断添加新行。

现在,我有一个 bash 文件,它连续运行 awk 程序以提取三个不同文件中的 (速度)、(纬度、经度) 和 (UTC 时间戳)。这是 bash 脚本:

#!/bin/sh
echo "Starting GPS info gathering"
while true; do
    awk -F, -f gpsgetinfo.awk gpsoutput.tr

 done

最后,我的 awk 程序非常简单,我希望它不断地从 gpsoutput.tr 文件读取最新记录并提取上述信息,在三个单独的文件里。awk 程序(gpsgetinfo.awk)如下:

BEGIN {
    FS = ","; 
    OFS = " ";

    while ((getline < "gpsoutput.tr") > 0) {


        if($1=="$GPRMC") {
                converted = $8*1.852; 
                printf $4 " " $6 "\n" >> "data1.txt";
                printf "%.3f \n", converted >> "speed.txt";
                printf $2 "\n" >> "gpstime.txt";
        }


    }
}


END {
    fflush();
}

问题是,在我的程序输出文件(data1.txtspeed.txtgpstime.txt)中awk,相同的输出重复多次,并且在几秒钟内,文件大小就达到了兆字节的大小。说清楚一点。这是我的 utc 时间输出文件的样子:

095546.000
095547.000
095546.000
095547.000
095546.000
095547.000
095546.000
095547.000
095546.000
095547.000
095546.000
095547.000
095546.000

并且在文件中重复数百次。

而 gpstime.tr 中的预期输出应该只是:

095546.000
095547.000
095548.000
095549.000
095550.000
095551.000

等等...因为每 1 秒接收一次 GPS 信号。

gpsoutput.tr保存 nmea 数据的文件只有几 kbs,并且没有任何重复数据。

谁能告诉我。为什么输出文件有这么多重复的值?我也尝试过使用printf $4 " " $6 "\n" > "data1.txt";(single>而不是>>),但对我来说不起作用。

答案1

问题确实如@Lekensteyn 所解释的那样。由于文件不断增大,您awk将始终重复已处理过的行。不幸的是,使用tail -f并不是解决方案,因为这种情况会永远持续下去,而 awk 不会打印任何内容。

相反,使用与@Lekensteyn 建议的相同的脚本,但>改为>>

#!/usr/bin/awk -f
BEGIN {
    FS = ",";
}
$1 == "$GPRMC" {
    converted = $8*1.852; 
    print $4, $6 > "data1.txt";
    printf "%.3f \n", converted > "speed.txt";
    print $2 > "gpstime.txt";
}

然后每秒运行该脚本来重新创建输出文件:

#!/bin/sh
echo "Starting GPS info gathering"
while true; do
    ./gpsgetinfo.awk gpsoutput.tr    
 done

答案2

如果 GPS 数据文件只会增长而不是被覆盖,那么您将一遍又一遍地写入相同的数据,这就是获得重复数据的原因。

您必须以某种方式不断向 awk 输入新行。可以使用以下命令完成此操作tail --follow

tail -f gpsoutput.tr | ./gpsoutput.awk

您的gpsoutput.awk应为这个可执行脚本:

#!/usr/bin/awk -f
BEGIN {
    FS = ",";
}
$1 == "$GPRMC" {
    converted = $8*1.852; 
    print $4, $6 >> "data1.txt";
    printf "%.3f \n", converted >> "speed.txt";
    print $2 >> "gpstime.txt";
    # Optional: add fflush() here.
}

相关内容