Как сократить часть из файла журнала?

Когда Vim читает существующий файл, он пытается обнаружить кодирование файла. При выписывании файла Vim использует файл, кодирующий это, он обнаружил (кроме тех случаев, когда Вы говорите его по-другому). Так файл, обнаруженный, поскольку, UTF-8 записан как UTF-8, файл, обнаруженный, как латинский 1 записан как латинский 1 и так далее.

По умолчанию процесс обнаружения сыр. Каждый файл, который Вы открываете с Vim, как будет предполагаться, будет латинский 1, если он не обнаружит метку порядка байтов Unicode наверху. Файл UTF-8 без метки порядка байтов будет трудно отредактировать, потому что любые многобайтовые символы покажут в буфере как последовательности символов вместо отдельных символов.

Хуже, Vim, по умолчанию, использует латинский 1 для представления текста в буфере. Таким образом, файл UTF-8 с меткой порядка байтов будет поврежден понижающим преобразованием к латинскому 1.

Решение состоит в том, чтобы настроить Vim для использования UTF-8 внутренне. Это, на самом деле, рекомендуется в документации Vim и единственной причине, она не настроена, тот выход из поля состоит в том, чтобы не создавать огромный беспорядок среди пользователей, которые ожидают, что Vim будет действовать в основном в качестве латинского 1 редактора.

В Вашем .vimrc, добавить set encoding=utf-8 и Vim перезапуска.

Или вместо этого, установите LANG переменная среды, чтобы указать, что UTF-8 является Вашей предпочтительной кодировкой символов. Это будет влиять не только на Vim, но и любое программное обеспечение, которое полагается LANG определить, как это должно представить текст. Например, чтобы указать, что текст должен появиться на английском языке (en), как говорится в Соединенных Штатах (US), закодированный как UTF-8 (utf-8), набор LANG=en_US.utf-8.

Теперь Vim будет использовать UTF-8 для представления текста в буфере. Плюс, это также приложит более решительное усилие для обнаружения кодировки UTF-8 в файле. Помимо поиска метки порядка байтов, это также проверит на UTF-8 без метки порядка байтов перед отступанием к латинскому 1. Таким образом, это больше не будет повреждать файл, кодированный в UTF-8, и это должно правильно отобразить символы UTF-8 во время сессии редактирования.

Для получения дополнительной информации о том, как Vim обнаруживает кодирование файла, посмотрите fileencodings опция в документации Vim.

Для получения дополнительной информации об установке кодирования, которое Vim использует внутренне, посмотрите encoding опция.

Если необходимо переопределить кодирование, используемое при обратной записи файла к диску посмотрите fileencoding опция.

18
19.11.2014, 21:23
6 ответов

Что-то как

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"
12
27.01.2020, 19:46
  • 1
  • 2
    @dogbane: да, да. Отредактированный. Я уверен, что Вы иногда пишете меньше, чем оптимальный код, он заслуживает такого резкого комментария? примечание –  asoundmove 25.02.2011, 17:43
  • 3
    : Если будет несколько последовательных строк 'первого свидания' с той же датой, то все кроме первого не будут удалены и будут представлены выводу... просто что-то для знания... (это зависит от ситуации), –  Peter.O 25.02.2011, 18:40
  • 4
    ..., но, даже при том, что я pro-sed ++, я думаю, что это конкретное задание вне его пределов для чего-либо кроме одного' собственного персонального инструмента.. Вот основной вопрос sed, имеет в этом случае (Ваш и мой.. Мне удалось заставить sed делать то же как Ваш.. это также работало в 1%).. назад к основному вопросу.. (который не относится к awk).... Ошибка (не закрепляемый): Относительно даты, которая допустима в рамках журнала, но на самом деле не присутствует в журнале, в случае 1-го аргумента, заставит sed ничего не печатать, и в случае 2-го аргумента, sed wil, чтобы печатать все после первого свидания!... еще... –  Peter.O 01.03.2011, 15:01
  • 5
    Другой, закрепляемая ошибка: это, это в настоящее время соответствует датам anywhewere в любой строке, включая часть данных, но это - просто тонкая настройка regex.. И для любого желающего использовать это, возможно, Вы могли прокомментировать, что args теперь обращаются к первым и последним датам в диапазоне (не-1 и +1).. и наконец.. мои "обременительные стандарты" не являются моими. Я - только средство рассылки запроса Корреспондентов... Пользователь заметит, работает ли это согласно просьбе, или нет.. Это было большим вопросом для меня.. Я изучил много :)... и меня довольный знать это sed может соответствовать awk для скорости, и это было на самом деле немного быстрее. –  Peter.O 01.03.2011, 15:13

Для печати всего между НЕЧТО и ПАНЕЛЬЮ включительно попробуйте:

$ sed -n '/FOO/,/BAR/p' file.txt
6
27.01.2020, 19:46
  • 1
    : Это только распечатает первую ПАНЕЛЬ серии последовательных ПАНЕЛЕЙ... примечание –  Peter.O 25.02.2011, 18:35
  • 2
    другое примечание... Большая проблема, если любая из дат не присутствует в данных.. Если последняя дата не будет присутствовать, то sed будет продолжать производить строки, пока это не достигнет EOF. –  Peter.O 26.02.2011, 20:48

Это сделает то, что Вы хотите...
И Включая и, Исключая даты параметра показаны.

# 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... Вот является пример fo данными тестирования

    98  2011-02-05 xxxx
    99  2011-02-05 xxxx
   100  2011-02-06 xxxx
   101  2011-02-06 xxxx

И вот генератор данных для тестирования.

5
27.01.2020, 19:46
  • 1
    я записал бы это (взятие первого, например) немного проще таким образом: awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file" –  asoundmove 28.02.2011, 23:17
  • 2
    @asoundmove: Да, это может выглядеть лучше, и это является определенно более стандартным, но в действительности, его время выполнения является только продолжительностью 1 дополнительного if оператор всего (даже 1 на строку) т.е. логический поток является эффективно тем же, и различие во время выполнения считалось бы в наносекундах.... Единственная причина, которую я не использовал "еще", состоит в том, что это - эффективно мое самое первое awk сценарий (кроме одного дня 4 года назад, когда я играл с некоторыми примерами)... и это - первый осуществимый механизм ответвления, который я нашел... (и, как упомянуто. это столь же быстро).. Я использование generly sed Попробовать q –  Peter.O 01.03.2011, 04:37
  • 3
    , который я не понимаю, где Вы даете название и местоположение текстового файла в этом методе? может кто-то помогать мне видеть через мою глупость –  Giles 11.07.2016, 15:14

Если в Вашем файле журнала у Вас есть даты в этом формате YYYY-MM-DD, затем, для нахождения всех записей для говорят, 10.02.2011, можно сделать:

grep 2011-02-10 log_file

Теперь, скажем, если Вы хотите найти записи на 10.02.2011 и 11.02.2011, затем, снова использование grep но с несколькими шаблонами:

grep -E '2011-02-10|2011-02-11' log_file
4
27.01.2020, 19:46
  • 1
    Хороший. Это работает, "как рекламируется" :)... Однако grep будет искать весь файл, даже если диапазон дат будет в начале файла. В среднем это удваивает время поиска, по сравнению с "exit-after-last-item-in-range"... Я только потрудился упоминать это из-за размера файла на 8 ГБ, упомянутого в вопросе, Ваши grep результаты времени почти идентичны sed примеру здесь (1 минута 58 секунд). Вот ссылка на мои тестовые результаты времени: paste.ubuntu.com/573477 –  Peter.O 28.02.2011, 18:57

Работа с этим размером файлов всегда трудна.

Путь вперед мог состоять в том, чтобы разделить этот файл на пару маленьких, чтобы сделать это можно использовать команду разделения.

split -d -l 50000 ToBigFile.data file_

Даже Вы, это разделено, можно все еще работать с файлом как то, если был бы тот с помощью удара для цикла

for f in `ls file_*`; do cat $f; done;

Но вместо кошки можно использовать инвертированный grep для избавлений от нежелательных данных, которые не важны для этого. (или вид улучшения, в котором Вы нуждаетесь).

В этой точке Вы будете просто работать с большим количеством меньших файлов, и команды, другие упомянутые выше будут работать, задыхаются на большом количестве меньших файлов.

И когда Вы сделаны, можно использовать секунду для цикла для создания нового меньшего файла снова.

for f in `ls file_*`; do cat $f >> NewFile.data ; done;

Обновление, Так как мы начинаем разделять данные в нескольких файлах, там будет большой работой с жестким диском, и это занимает время. (В этом вопросе, по-видимому, 5 минут).

С другой стороны, следующие шаги, вероятно, были бы быстрее.

Таким образом, этот метод, вероятно, бессмыслен для простого grep, awk, sed операция, но если шаблоны поиска становятся более сложными, это могло бы стать быстрее.

1
27.01.2020, 19:46
  • 1
    Johanm, это берет awk и sed, только 1 минута, в среднем, для поиска файла журнала на 8 ГБ на моем компьютере, и на том же compuer, просто inital разделение файла, занимает 4 минуты 43 секунды... :) –  Peter.O 01.03.2011, 15:49
  • 2
    Скажем, то, что Вы могли сократить те awk и sed времена на 50% на меньших файлах. Затем мы все еще должны сделать больше чем 10 из тех операция, прежде чем мы получим на общем времени... Таким образом, возможно, разделение файла не является лучшей идеей для нескольких регрессий... –  Johan 01.03.2011, 17:03
  • 3
    awk сценарий мог (легко) быть изменен для вывода 10 различных результатов поиска в 10 файлов.. в одной единственной передаче, но это замедлило бы чтение в то время как на самом деле вывод отчеты... Sed мог также сделать то же, но как я упомянул в комментариях asoundmove, sed перестанет работать, если конкретная дата/время не будет иметь никакой записи в журнале (например, Вы ищете по часам).. Я использую sed много, и это чрезвычайно полезно, но это имеет свои пределы... Вот sed FAQ о том, когда использовать sed по сравнению с awk.. Я не обязательно соглашаюсь со всем этим, но я вижу то, что они имеют в виду... sed.sourceforge.net/sedfaq6.html –  Peter.O 02.03.2011, 06:12
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file
0
27.01.2020, 19:46
  • 1
    Это только распечатает первую запись в журнале на 25.02.2011 все же. –  Gilles 'SO- stop being evil' 25.02.2011, 21:54

Теги

Похожие вопросы