快速和可读的方式在沙尔这样做。 这似乎比现金版快。 (配制时间用内部模块显示,该模块从该代码中删除)
./ext_lines.py -v -s Feb 12 00:23:00 -e Feb 15 00:23:00 -i /var/log/syslog.1
Total time : 445 ms 187 musec
Time per line : 7 musec 58 ns
Number of lines : 63,072
Number of extracted lines : 29,265
I can t compare this code with the daemon.log file used by others... But, here is my config
Operating System: Kubuntu 22.10
KDE Plasma Version: 5.25.5
KDE Frameworks Version: 5.98.0
Qt Version: 5.15.6
Kernel Version: 6.2.0-060200rc8-generic (64-bit)
Graphics Platform: X11
Processors: 16 × AMD Ryzen 7 5700U with Radeon Graphics
Memory: 14.9 GiB of RAM
The essential code could fit in just one line (dts = ...), but to make it more readable it s being "splited" in three. It s not only rather fast, it s also very compact :-)
from argparse import ArgumentParser, FileType
from datetime import datetime
from os.path import basename
from sys import argv, float_info
from time import mktime, localtime, strptime
__version__ = 1.0.0 # Workaround (internal use)
now = datetime.now
progname = basename(argv[0])
parser = ArgumentParser(description = Is Python strptime faster than sed and Perl ? ,
prog = progname)
parser.add_argument( --version ,
dest = version ,
action = version ,
version = {} : {} .format(progname,
str(__version__)))
parser.add_argument( -i ,
--input ,
dest = infile ,
default = /var/log/syslog.1 ,
type = FileType( r ,
encoding = UTF-8 ),
help = Input file (stdin not yet supported) )
parser.add_argument( -f ,
--format ,
dest = fmt ,
default = %b %d %H:%M:%S ,
help = Date input format )
parser.add_argument( -s ,
--start ,
dest = start ,
default = None,
help = Starting date : >= )
parser.add_argument( -e ,
--end ,
dest = end ,
default = None,
help = Ending date : <= )
parser.add_argument( -v ,
dest = verbose ,
action = store_true ,
default = False,
help = Verbose mode )
args = parser.parse_args()
verbose = args.verbose
start = args.start
end = args.end
infile = args.infile
fmt = args.fmt
############### Start code ################
lines = tuple(infile)
# Use defaut values if start or end are undefined
if not start :
start = lines[0][:14]
if not end :
end = lines[-1][:14]
# Convert start and end to timestamp
start = mktime(strptime(start,
fmt))
end = mktime(strptime(end,
fmt))
# Extract matching lines
t1 = now()
dts = [(x, line) for x, line in [(mktime(strptime(line[:14 ],
fmt)),
line) for line in lines] if start <= x <= end]
t2 = now()
# Print stats
if verbose :
total_time = Total time
time_p_line = Time per line
n_lines = Number of lines
n_ext_lines = Number of extracted lines
print(f {total_time:<25} : {((t2 - t1) * 1000)} ms )
print(f {time_p_line:<25} : {((t2 -t1) / len(lines) * 1000)} ms )
print(f {n_lines:<25} : {len(lines):,} )
print(f {n_ext_lines:<25} : {len(dts):,} )
# Print extracted lines
print( .join([x[1] for x in dts]))