我想找到名字和年龄相同但日期不同的记录。然后,如果有一个前一行日期和下一行日期之间的差距,我必须填补差距。
样本数据文件. txt
20230907,Allan,29,Marketing
20230912,Allan,29,VirtualAssistant
20230913,Allan,29,Programmer
20230920,Daniel,28,Engineer
20230922,Daniel,28, Photographer
到目前为止我所做的:
#create zero byte file for all filled gaps
cat /dev/null > fillGap.txt
For line in `awk -F"," '{print $2","$3}' file.txt`;do
#if name,age NOT found in fillGap.txt then grep everything that matches in file.txt
if [[ -z `grep -w ${line} fillGap.txt` ]];then
grep -w ${line} file.txt > MatchNameAge.txt
#this is the part of checking if there is a gap between dates and if so, gaps will be filled. I haven't figured it out on how I should do it. maybe you could help me
#after filling the gap, the transformed will be appended in fileGap.txt
else
#if name,age have already found in filledGap.txt, there's nothing to do.
fi
done
我的代码缺乏大量的上下文,因为我只有想法,并继续一点一点地尝试如何编码。
这个想法可能工作得很好,但是,对大文件使用for循环会导致长时间运行。
你能帮助我实现目标,尽可能缩短运行时间?
预期输出:
20230907,Allan,29,Marketing
20230908,Allan,29,Marketing
20230909,Allan,29,Marketing
20230910,Allan,29,Marketing
20230911,Allan,29,Marketing
20230912,Allan,29,VirtualAssistant
20230913,Allan,29,Programmer
20230920,Daniel,28,Engineer
20230921,Daniel,28,Engineer
20230922,Daniel,28, Photographer
我想你添加这样的情况下在我的数据如下。如果我有一个日期是月底,下一个日期是下个月,
20230930,Allan,29,Programmer
20231004,Allan,29,Engineer
输出应该如下所示
20230930,Allan,29,Programmer
20231001,Allan,29,Programmer
20231002,Allan,29,Programmer
20231003,Allan,29,Programmer
20231004,Allan,29,Engineer
重要的是,用相同的“名字,年龄”来填补日期之间的空白
6条答案
按热度按时间xesrikrc1#
使用任何
sort
加上GNU awk的时间函数和gensub()
:或者,使用任何awk只需将上面的
nextDate()
函数替换为以下版本:wko9yo5t2#
在
awk
中处理日期有点棘手,所以我倾向于编写专门的函数来处理它们。下面是一个假设排序输入的示例解决方案(使用
gawk
和mawk
进行测试):这样运行:
输出量:
pengsaosao3#
TXR中的解决方案:
filldate.txr
中的代码:用Vim着色:
rdrgkggo4#
这可能对你有用(GNU sed和date):
使用
N;P;D
sed习惯用法,将下一行追加到当前行,打印/删除第一行并重复。在这种情况下,如果模式空间中有一行或没有其他行,则追加下一行。
比较这些行的第二个和第三个字段,如果相同:
比较这些行的日期,如果相同,则删除第一行并重复。
如果日期不同,请在第一行和第二行之间插入一行明天的日期。
无论如何,打印/删除第一行并重复。
注意:工作的主要部分是由需要插值echo命令的求值替换完成的。
如果文件未排序,则用途:
wpx232ag5#
使用sqlite3:
mktemp
)file.txt
。这是使用我能想到的最简单的名称来完成的,所以第一列将命名为a
,第二列将命名为b
,.(见注解)20230907
变成2023-09-07
。这样SQLite明天就可以使用date('2023-09-07','1 day')
进行计算。-
时,日期中的符号再次被删除。cte
根据lead(a) over (partition by b order by a)
的值添加记录,lead(a) over (partition by b order by a)
是个人可用的下一个数据。注意:我不应该改变原来的输入,但使用另一个临时文件,.
注2:因为CSV是一种奇怪的格式,所以
Photographer
的输出不是您所期望的。输出为" Photographer"
。更多关于这方面的阅读,请参阅:Spaces between separator and value in csv fileuqzxnwby6#
这里有一种方法可以做到这一点,而不需要以大量正则表达式为代价不停地调用
mktime()
和strftime()
(它应该能够处理所有闰年计算):