我正在处理一个脚本,该脚本需要从单个文本文件中获取重复的行,并更改日期字段上的值,但只更改时间字段。字段分隔符是TAB所以......
# cat enviando4
1414743351 2014-11-01 09:00:00
1414743351 2014-10-31 09:15:51
1414743351 2014-10-30 23:00:00
1414743351 2014-10-31 09:15:51
1414743351 2014-10-30 23:00:00
1414743351 2014-10-31 10:25:00
1414743351 2014-10-31 09:15:51
1414743351 2014-11-01 10:25:00
我按日期排序:
/ bin / sort enviando4 -k2 -t $' \ t' -o enviando4
# cat enviando4
1414743351 2014-10-30 23:00:00
1414743351 2014-10-30 23:00:00
1414743351 2014-10-31 09:15:51
1414743351 2014-10-31 09:15:51
1414743351 2014-10-31 09:15:51
1414743351 2014-10-31 10:25:00
1414743351 2014-11-01 09:00:00
1414743351 2014-11-01 10:25:00
现在我需要向任何重复的日期添加至少4分钟(从不减去),因此我将只有唯一的日期。它看起来像这样:
# cat enviando4
1414743351 2014-10-30 23:04:00 --> add 4
1414743351 2014-10-30 23:00:00 --> no change
1414743351 2014-10-31 09:19:51 --> add 4
1414743351 2014-10-31 09:23:51 --> add 8
1414743351 2014-10-31 09:15:51 --> no change
1414743351 2014-10-31 10:25:00 --> unique, no change
1414743351 2014-11-01 09:00:00 --> unique, no change
1414743351 2014-11-01 10:25:00 --> unique, no change
并验证这些更改未产生新的重复值。 我坚持这个。 谢谢。
答案 0 :(得分:0)
你的任务并不困难。 Bash拥有出色的日期操作工具。您需要做的是sort the original
列表,然后是read each line
已排序文件,compare the date/time to the previous
日期时间并使用计数器,将重复时间增加counter * 4min
偏移量,并且write the new date/time to your output file.
有很多方法可以处理时间调整。最简单的方法是将日期/时间字符串转换为自纪元以来的秒数。然后只需将偏移量添加到重复时间并将其转换回所需的日期/时间格式。
以下示例显示了执行此操作的一种方法。有几个操作可以组合,但我将偏移计算分开,以使其更具可读性。该脚本将输入文件作为第一个参数(我将其默认设置为dat/env4.dat
用于我的测试,并根据需要设置)。然后脚本将分类到临时文件,读取临时文件,将时间调整为重复,然后将输出写入inputfile.out
,在退出之前删除临时文件。如果您有任何问题,请与我联系:
#!/bin/bash
ifn="${1:-dat/env4.dat}" # set input filename (ifn) and validate
[ -r "$ifn" ] || {
printf "\n Error: input file not readable. Usage: %s [<filename> (dat/env4.dat)]\n\n" "${0//*\//}" >&2
exit 1
}
## initialize variables
tfn="/tmp/${ifn//*\//}.tmp" # set temp filename (tfn)
ofn="${ifn}.out" # set output filename (ofn)
:> "$ofn" # truncate output file
pdate=0 # initialize prior date
cnt=0 # counter variable
tos=240 # time offset in seconds (4 min.)
tse=0 # time since epoch in seconds
sort "$ifn" > "$tfn" # sort input file into temp file & validate
[ -r "$tfn" ] || {
printf "\n Error: sort failed to produce a tmp file or tmp file not readable\n\n" >&2
exit 1
}
## read temp file into index/idate and add 4 min to each successive duplicate
while read -r index idate || [ -n "$idate" ]; do
if [ "$pdate" = "$idate" ]; then
tse=$(date -d "$idate" +%s) # get time since epoch for idate
cnt=$((cnt+1)) # increase counter
nos=$((cnt*tos)) # set new time offset (not Nitrous Oxide)
ntm=$((tse+nos)) # set new time including offset
# write new time to output
printf "%s\t%s\n" "$index" "$(date -d "@${ntm}" +"%F %T" )" >> "$ofn"
else
cnt=0; nos=0 # reset counter and new time offset
# write output unchanged
printf "%s\t%s\n" "$index" "$idate" >> "$ofn"
fi
pdate="$idate" # save current date/time as prior date/time
done <"$tfn"
[ -r "$tfn" ] && rm "$tfn" # remove temp file
输入文件:
$ cat dat/env4.dat
1414743351 2014-11-01 09:00:00
1414743351 2014-10-31 09:15:51
1414743351 2014-10-30 23:00:00
1414743351 2014-10-31 09:15:51
1414743351 2014-10-30 23:00:00
1414743351 2014-10-31 10:25:00
1414743351 2014-10-31 09:15:51
1414743351 2014-11-01 10:25:00
输出文件:
$ cat dat/env4.dat.out
1414743351 2014-10-30 23:00:00
1414743351 2014-10-30 23:04:00
1414743351 2014-10-31 09:15:51
1414743351 2014-10-31 09:19:51
1414743351 2014-10-31 09:23:51
1414743351 2014-10-31 10:25:00
1414743351 2014-11-01 09:00:00
1414743351 2014-11-01 10:25:00
注意:如果您想要翻转重复项以便首先显示较大的偏移时间,则应该可以对输出文件进行操作。在offset while loop
中执行此操作会使逻辑过于复杂,以达到此问题的目的。如果要在offset while loop
中包含附加代码,基本方法是将先前日期和任何匹配日期存储在数组中,然后偏移数组日期/时间值并按相反顺序写出。每次遇到新的日期/时间时都取消设置数组。
包含电子邮件和调整字段的附录
如果您有兴趣添加到输出中,以便在开头添加e-mail
,然后在time adjustment
和date portion
之间加入time portion
{1}},只需在开头添加电子邮件,然后将new date field
返回的新字符串拆分为date
和date part
并插入{{1}即可轻松完成此操作在输出中的两个之间。无论您使用time part
还是00:0n:00
都没有区别。 printf
更加灵活,但有时候echo
也会带来优势。
注意:,在下面的代码中,我形成printf
(echo
为00:0n:000
,假设只有2个重复。如果有3个或更多,如果调整后的时间大于n
(例如4, 8, etc..
重复00:nn:00
),则必须处理此问题以调整逻辑以形成8 minutes
。
如果您有进一步的问题,请告诉我。
12, 16, 20, ...
输出文件:(使用相同的输入)
3rd, 4th, 5th, ...