У меня есть файл журнала 8 Гб (журнал производства Rails). Мне нужно сократить это между некоторыми датами (линиями). Какую команду я могу использовать для этого?
sed
сделаем это легко.
У меня есть файл журнала 8 Гб (журнал производства 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 на строку), т.е. логический поток фактически такой же, и разница во времени выполнения будет подсчитываться в наносекундах .... Единственная причина, по которой я не использовал "else", заключается в том, что это фактически мой первый 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
будет искать весь файл, даже если диапазон дат находится в начале файла. В среднем это удваивает время поиска, по сравнению с «exit-after-last-item-in-range» ... Я только затрудняюсь упомянуть это из-за размера файла 8 ГБ, упомянутого в вопросе, Ваш Результаты grep time практически идентичны приведенному здесь примеру sed (1 мин 58 с). Вот ссылка на мои результаты тестов времени: paste.ubuntu.com/573477
Работать с файлами такого размера всегда сложно.
Путь вперед может состоять в том, чтобы разбить этот файл на пару маленьких, для этого вы можете использовать команду split.
split -d -l 50000 ToBigFile.data file_
Даже если он разделен, вы все равно можете работать с файлом, как если бы он использовал цикл bash for
for f in `ls file_*`; do cat $f; done;
Но вместо кошки вы можете использовать инвертированный grep, чтобы избавиться от нежелательных данных, что для этого не имеет значения. (или вид уточнения, который вам нужен).
На этом этапе вы будете просто работать с большим количеством файлов меньшего размера, а команды, упомянутые выше, будут работать с большим количеством файлов меньшего размера.
И когда вы закончите, вы можете использовать второй цикл for, чтобы снова создать новый файл меньшего размера.
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