Недавно я писав про видобування шматка лога FreeRadius за допомогою невеличкого скрипта на awk. Чомусь я тоді вирішив, що на awk буде простіше, чи що.
Ось аналогічний за функціональністю шматочок на Python:
#!/usr/bin/python # # import sys, re pattern = sys.argv[1] file = open(sys.argv[2]) cp = re.compile(pattern) total = 0 selected = 0 good = False lines = 0 set = [] while True: line = file.readline() if not line: break lines += 1 set.append(line) if cp.search(line): good = True if line == '\n': if good: print ''.join(set), selected += 1 good = False set = [] total += 1 sys.stderr.write("%i records (%i lines) processed\n" %(total, lines)) sys.stderr.write("%i records matched\n" % selected) sys.stderr.write("Pattern was: '%s'\n\n" % pattern) |
В принципі, нічого особливого.
Що тут цікаво? — що цей скрипт на Python працює у відсотків на 30 швидше за аналогічний на awk. І я не знаю, як я можу опимізувати попередній варіант :-)
Дивіться, це awk:
time awk -f cutlog.awk pattern='Station-Id = \"XXXYYZ[0-2]\"' detail-YYYYMMDD > detail-YYYYMMDD.part 276358 records (6874776 lines) processed 49574 records matched Pattern was: 'Station-Id = "XXXYYZ[0-2]"' 33.90user 0.29system 0:34.19elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+306minor)pagefaults 0swaps |
А це Python:
time python cutlog.py 'Station-Id = "XXXYYZ[0-2]"' detail-YYYYMMDD > detail-YYYYMMDD.part 276358 records (6874776 lines) processed 49574 records matched Pattern was: 'Station-Id = "XXXYYZ[0-2]"' 26.60user 0.24system 0:26.85elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+732minor)pagefaults 0swaps |
update:
Я таки спробував «оптимізувати»:
# замість: if cp.search(line): good = True # написати: if not good and cp.search(line): good = True continue # і аналогічно для awk. |
Різниці практично ніякої. Так само практично не впливає порядок перевірки (спочатку «чи порожній рядок», а потім «чи містить потрібне» — чи навпаки), використання print
замість printf
тощо.