AWK字符串/子字符串操作失去原始格式



你好,我有以下文件:

P:TWS.XAUUSD    07:34:47.872000 0       1306.73 1000    1306.87 500     0       0       99
P:TWS.XAUUSD    07:34:47.876000 0       1306.7  500     1306.87 500     0       0       99
P:TWS.XAUUSD    07:34:47.877000 0       1306.7  500     1306.85 500     0       0       99

我想更改第二列($2)的时间戳,并将其减少1小时。

我使用awk,并将第二个字段拆分为2个单独的子字符串,但是当我使用以下代码时:

awk '{print $1,substr($2,1,2)-1 substr($2,3,13),$3,$4,$5,$6,$7,$8,$9,$10}'

我的输出如下所示

P:TWS.XAUUSD 6:34:47.872000 0 1306.73 1000 1306.87 500 0 0 99
P:TWS.XAUUSD 6:34:47.876000 0 1306.7 500 1306.87 500 0 0 99
P:TWS.XAUUSD 6:34:47.877000 0 1306.7 500 1306.85 500 0 0 99

计算和信息是正确的,但是我正在丢失格式(我要求小时HH列是2位数)。

如何执行相同的计算并保持原始格式。

我尝试使用printf命令,但是我似乎无法提取多个字段,并获得我需要的整行。

awk '{printf ("%02dn"),$2-1}'

给出如下输出

06
06
06

如何将printprintf放在一起?

一个特定于gawk的解决方案,保留原始的精确间距:

gawk 'BEGIN {FIELDWIDTHS = "16 2 72"}{printf("%s%02d%sn", $1, ($2-1>0?$2-1:23), $3)}' file

当然,同样的事情可以很容易地用子字符串完成。

我建议使用awk的时间函数来进行时间计算:

awk '
    BEGIN { date = strftime("%Y %m %d", systime()) }
    {
        split($2, a, /[:.]/)
        t = mktime(date" "a[1]-1" "a[2]" "a[3])
        $2 = strftime("%T",t) "." a[4]
        print
    }
' file

这样做的好处是,当时间为"00:00:00"时,可以将时间打印为"23:00:00"而不是"-1:00:00"

每年有几个小时(夏令时转换),这种过于简单的算法会给出错误的结果。

使用OFS='t'(输出字段分隔符):

awk '{print $1,substr($2,1,2)-1 substr($2,3,13),$3,$4,$5,$6,$7,$8,$9,$10}' OFS='t' file
P:TWS.XAUUSD    6:34:47.872000  0   1306.73 1000    1306.87 500 0   0   99
P:TWS.XAUUSD    6:34:47.876000  0   1306.7  500 1306.87 500 0   0   99
P:TWS.XAUUSD    6:34:47.877000  0   1306.7  500 1306.85 500 0   0   99

如果您可以使用perl,则:

$ cat file
P:TWS.XAUUSD    07:34:47.872000 0       1306.73 1000    1306.87 500     0       0       99
P:TWS.XAUUSD    07:34:47.876000 0       1306.7  500     1306.87 500     0       0       99
P:TWS.XAUUSD    07:34:47.877000 0       1306.7  500     1306.85 500     0       0       99

$ perl -pe 's/(d+)/sprintf "%02d", ($1-1>0?$1-1:23)/e' file
P:TWS.XAUUSD    06:34:47.872000 0       1306.73 1000    1306.87 500     0       0       99
P:TWS.XAUUSD    06:34:47.876000 0       1306.7  500     1306.87 500     0       0       99
P:TWS.XAUUSD    06:34:47.877000 0       1306.7  500     1306.85 500     0       0       99

您也可以通过管道将输出输出到列命令

[nabeel@nmoidu ~]$ awk '{print $1,substr($2,1,2)-1 substr($2,3,13),$3,$4,$5,$6,$7,$8,$9,$10}' test | column -t
P:TWS.XAUUSD  6:34:47.872000  0  1306.73  1000  1306.87  500  0  0  99
P:TWS.XAUUSD  6:34:47.876000  0  1306.7   500   1306.87  500  0  0  99
P:TWS.XAUUSD  6:34:47.877000  0  1306.7   500   1306.85  500  0  0  99

相关内容

最新更新