你的任務並不困難。 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
注:如果您想翻轉重複,以便更大的抵消時間首先出現,你應該可以操作e在輸出文件上。在offset while loop
內執行此操作會使此問題的邏輯過於複雜。如果要在offset while loop
中包含附加代碼,基本方法是將先前日期和任何匹配日期存儲在數組中,然後對陣列日期/時間值進行偏移並將其按相反順序寫出。每遇到新的日期/時間,請取消設置陣列。
附錄包括電子郵件和調整現場
如果您有興趣增加在輸出到包括e-mail
開頭,然後包括在time adjustment
的date portion
和time portion
之間在new date field
,你可以通過簡單地在開始添加電子郵件,然後通過分割返回date
新串入date part
和time part
並在輸出插入兩者之間00:0n:00
這樣做比較容易。無論您使用printf
還是echo
都沒有區別。 printf
更加靈活,但有些時候echo
也提供了優勢。
注意:在下面的代碼,我形成00:0n:000
(與n
是4, 8, etc..
假定只有2重複如果有3個或更多,你將不得不處理該調整邏輯以形成00:nn:00
如果調整。時間比8 minutes
(例如12, 16, 20, ...
爲3rd, 4th, 5th, ...
一式兩份)。更大的
讓我知道,如果你有進一步的問題。
## beginning part of script unchanged
# tse=0 # time since epoch in seconds
email="[email protected]" # email to output
adjtm=4 # simple value to provide adjustment in 00:04:00, etc.
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
adj=$((cnt*adjtm)) # compute 4, 8, ... for 00:0n:00 output
nos=$((cnt*tos)) # set new time offset (not Nitrous Oxide)
ntm=$((tse+nos)) # set new time including offset
ndt="$(date -d "@${ntm}" +"%F %T")" # new date/time value
nd1=${ndt% *} # date portion (first field) of ntd
nd2=${ndt#* } # time portion (second filed) of ntd
ncmb="$nd1 00:0${adj}:00 $nd2" # new combined "date 00:0n:00 time" string
# write new time to output
printf "%s\t%s\t%s\n" "$email" "$index" "$ncmb" >> "$ofn"
else
cnt=0; nos=0 # reset counter and new time offset
nd1=${idate% *} # date portion (first field) of idate
nd2=${idate#* } # time portion (second filed) of idate
ncmb="$nd1 00:00:00 $nd2" # new combined "date 00:00:00 time" string (no adj)
# write output unchanged
printf "%s\t%s\t%s\n" "$email" "$index" "$ncmb" >> "$ofn"
fi
pdate="$idate" # save current date as prior date
done <"$tfn"
[ -r "$tfn" ] && rm "$tfn" # remove temp file
輸出文件:(與相同輸入)
$ bash env4-2.sh
[email protected] 1414743351 2014-10-30 00:00:00 23:00:00
[email protected] 1414743351 2014-10-30 00:04:00 23:04:00
[email protected] 1414743351 2014-10-31 00:00:00 09:15:51
[email protected] 1414743351 2014-10-31 00:04:00 09:19:51
[email protected] 1414743351 2014-10-31 00:08:00 09:23:51
[email protected] 1414743351 2014-10-31 00:00:00 10:25:00
[email protected] 1414743351 2014-11-01 00:00:00 09:00:00
[email protected] 1414743351 2014-11-01 00:00:00 10:25:00
如果顛倒排序順序,那麼你將需要4分鐘添加到*最後*重複行 - 更容易在類似AWK做的事情 - 保持一條線在緩衝區中,檢查密鑰的更改,敲入持有的線路,... – Dinesh 2014-10-31 00:25:12