У мене є файл журналу 8 Gb (журнал виробництва Rails). Мені потрібно розрізати його між деякими датами (рядками). Яку команду я можу використати для цього?
sed
зробиш це легко.
У мене є файл журналу 8 Gb (журнал виробництва Rails). Мені потрібно розрізати його між деякими датами (рядками). Яку команду я можу використати для цього?
sed
зробиш це легко.
Відповіді:
Щось на зразок
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
дозволяє побачити на екрані, що вводиться у файл cut-log
.
Редагувати:
Щоб задовольнити жорсткі стандарти fred.bear, ось рішення sed (хоча, мабуть, рішення awk набагато красуніше):
b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"
sed
може відповідати awk
швидкості, і це було насправді трохи швидше.
Щоб надрукувати все між FOO та BAR включно, спробуйте:
$ sed -n '/FOO/,/BAR/p' file.txt
Це зробить те, що ви хочете ...
Відображаються дати включення та виключення параметрів.
# set Test args
set 2011-02-24 2011-02-26 "junk"
from="$1"
till="$2"
file="$3"
# EITHER ==== +++++++++
# Ouptut lines between two parameter dates INCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 >= from) && ($2 <= till) { print $0 ; next }
($2 > till) { exit }' "$file"
# OR ======== ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 > from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
Він перевіряє (відсортовану) дату в полі 2 ... Ось приклад даних тесту
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
А ось генератор тестових даних .
awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
if
твердження загалом (навіть не 1 на рядок), тобто. логічний потік фактично однаковий, і різницю в часі виконання рахуватимуться в наносекундах ... Єдиною причиною, яку я не використовував "інше", є те, що це фактично мій перший в історії awk
сценарій (окрім дня 4 років тому, коли я грав з деякими прикладами) ... і це перший працюючий механізм гілки, який я знайшов ... (і як уже згадувалося. це так само швидко) .. Я загалом використовую sed
Tryq
Якщо у вашому файлі журналу є дати в такому форматі YYYY-MM-DD
, то, щоб знайти всі записи для, скажімо, 2011-02-10, ви можете зробити:
grep 2011-02-10 log_file
Скажімо, якщо ви хочете знайти записи для 2011-02-10 та 2011-02-11, тоді знову використовуйте, grep
але з кількома шаблонами:
grep -E '2011-02-10|2011-02-11' log_file
grep
буде шукати весь файл, навіть якщо діапазон дат знаходиться на початку файлу. В середньому це подвоює час пошуку в порівнянні з "вихід-після-останній-предмет-у-діапазоні" ... Мені це лише сподобається через розмір файлу в 8 Гб, згаданий у запитанні, результати греп-часу майже ідентичні прикладу sed (1 хв 58 сек). Ось посилання на результати моїх тестів за часом: paste.ubuntu.com/573477
Працювати з таким розміром файлів завжди важко.
Шлях вперед може бути розділити цей файл на пару маленьких, для цього можна скористатися командою split.
split -d -l 50000 ToBigFile.data file_
Навіть у вас це розділено, ви все одно можете працювати з файлом, як якщо б ви використовували bash для циклу
for f in `ls file_*`; do cat $f; done;
Але замість кота ви можете використовувати перевернуту греп для позбавлення від небажаних даних, що для цього не має значення. (або вид уточнення, який вам потрібен).
У цей момент ви просто працюватимете з великою кількістю менших файлів, а команди, згадані вище, працюватимуть більш бездоганно над багатьма меншими файлами.
І коли ви закінчите, ви можете використовувати секунду для циклу, щоб знову створити новий менший файл.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Оновлення Оскільки ми починаємо розділяти дані на кілька файлів, з жорстким диском буде багато роботи, і це потребує часу. (У цьому питанні, мабуть, 5хв).
З іншого боку, наступні кроки, ймовірно, будуть швидшими.
Тож цей метод, ймовірно, безглуздий для простої роботи grep, awk, sed, але якщо шаблони пошуку ускладняться, вони можуть стати швидшими.
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file