我在第4列中有一个文本文件,其日期值为YYYYMMDD格式,在第5列中有一个月的偏移量。
System.Data.SqlClient is not supported on this platform
我想将第5列中的值替换为 日期-d'(第4列中的值)-(第5列中的值)月+1个月'+'%Y%m%d'
因此最终结果应如下所示
a1|b1|c1|20190101|1|1|11|A|D
a1|b1|c1|20190101|2|2|12|B|E
a1|b1|c1|20190101|3|3|13|C|F
a2|b2|c2|20190101|1|4|14|G|J
a2|b2|c2|20190101|2|5|15|H|K
a2|b2|c2|20190101|3|6|16|I|L
我使用awk -f offsetMonths.awk绑定
a1|b1|c1|20190101|20190101|1|11|A|D
a1|b1|c1|20190101|20181201|2|12|B|E
a1|b1|c1|20190101|20181101|3|13|C|F
a2|b2|c2|20190101|20190101|4|14|G|J
a2|b2|c2|20190101|20181201|5|15|H|K
a2|b2|c2|20190101|20181101|6|16|I|L
我得到的是
BEGIN{
FS="|"
OFS = FS
}
{
# Date field is in column 4, offset is in column 5
# Replace column 5 with the offset date
"date -d '"$4" -"$5" months +1 months' +'%Y%m%d' " | getline l
$5 = l
print $0
}
请注意第4行到第6行中不正确的月份偏移值
答案 0 :(得分:3)
除了kvantour答案(这可能比我的回答更干净,因为我更喜欢使用awk内置函数而不是在awk中调用bash命令),这是固定的代码:
df %>% as_tibble() %>%
mutate(Score = as.numeric(Score)) %>%
spread(Pre_Post, Score) %>%
rename(Score_pre = `1`, Score_post = `2`) %>%
mutate(improve = if_else(Score_pre > Score_post, "0", "1")) %>%
group_by(improve) %>%
summarise(n = n()) %>%
mutate(percentage = n / sum(n))
# A tibble: 2 x 3
improve n percentage
<chr> <int> <dbl>
1 0 3 0.429
2 1 4 0.571
结果:
BEGIN{
FS="|"
OFS = FS
}
{
# Date field is in column 4, offset is in column 5
# Replace column 5 with the offset date
cmd = "date -d '"$4" -"$5-1" months' +'%Y%m%d'" # as suggested by @kvantour
cmd | getline result
close(cmd)
$5 = result
print $0
}
更多informations在这里。
在没有调用close()的情况下,awk会创建子进程来运行命令,直到最终用尽了用于更多管道的文件描述符为止。
答案 1 :(得分:3)
您无需为此调用外部char * buffer = new char[size + 1]; // size = 5, allocate 6 chars
InternetReadFile(request, buffer, size, &dwRead);
buffer [size] = '\0';
实用程序或特定于gawk的时间函数,这只是数学上的事情:
date
答案 2 :(得分:2)
使用GNU awk,任何日期转换都应使用提供的日期函数执行。此问题的两个有用的时间函数是mktime
和strftime
:
中的更多信息
mktime(datespec)
:将日期格式为datespec
的字符串YYYY MM DD hh mm ss
转换为Unix纪元时间,即总秒数自1970年1月1日UTC。从gawk-4.2.1开始,您可以使用utc-flag
来指示datespec
是否使用UTC。
strftime(format,timestamp)
:这会将历时timestamp
转换为格式化的字符串(与date
命令相同的格式)。您可以使用utc-flag
指示返回的时间应采用UTC或当地时区。
代码现在变为:convert.awk
BEGIN {FS=OFS="|"}
{ d=$4
time=mktime(substr(d,1,4)" "substr(d,5,2)+1-$5" "substr(d,7,2)" 00 00 00")
$5=strftime("%Y%m%d",time)
print
}' file
,然后使用以下命令运行它:
$ awk -f convert.awk file.txt
mktime
是 additive 。因此,您以YYYY MM DD hh mm ss
格式传递的字符串不需要是正确的日期,您可以使用不正确的值。例如,字符串2019 01 32 00 00 00
等效于2019 02 01 00 00 00
,字符串2019 5 -10 00 00 00
等效于2019 04 20 00 00 00
,甚至2019 -19 -10 00 00
等效于2017 04 20 00 00
注意:由于我们直接在mktime
中修改了时间,因此我们不必担心夏令时(请参阅注释)。