4

Учитывая файл журнала, я обычно делаю что-то вроде этого:

grep 'marker-1234' filter_log

Какая разница в использовании «» или «» или ничего в шаблоне?

Приведенная выше команда grep выдаст много тысяч строк; что я хочу В этих строках обычно есть одна порция данных, которую я ищу. Иногда я использую awk для распечатки полей, которые мне нужны. В этом случае формат журнала изменяется, я не могу полагаться исключительно на позицию, не говоря уже о том, что фактические зарегистрированные данные могут сдвинуть позицию вперед.

Чтобы сделать это понятным, допустим, что в строке журнала содержался IP-адрес, и это было все, что мне было нужно, так что позже я могу передать его для сортировки и уникальности и получить некоторые подсчеты.

Примером может быть:

2010-04-08 some logged data, indetermineate chars - [marker-1234] (123.123.123.123) from: foo@bar.example.com to bar@foo.example.com [stat-xyz9876]

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

Для этого примера достаточно использовать IP-адрес. Я старался. sed не в состоянии понять [0-9] {1,3}. как шаблон? Я должен был [0-9] [0-9] [0-9]. что дало странные результаты, пока весь шаблон не создан.

Это не относится к IP-адресу, шаблон изменится, но я могу использовать его как шаблон обучения.

Спасибо вам всем.

4 ответа4

7

Я не знаю, на какой ОС вы работаете, но во FreeBSD 7.0+ у grep есть опция -o которая возвращает только ту часть, которая соответствует шаблону. Чтобы ты мог
grep "marker-1234" filter_log | grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"

Возвращает список только IP-адресов из 'filter_log "...

Это работает в моей системе, но, опять же, я не знаю, что поддерживает ваша версия grep.

3

Вы можете сделать все это только одной командой awk . Нет необходимости использовать какие-либо другие инструменты

$ awk '/marker-1234/{for(o=1;o<=NF;o++){if($o~/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)print $o }  }' file
(123.123.123.123)
2

Вы можете сократить второй grep немного так:

grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'

Чтобы ответить на ваш первый вопрос, двойные кавычки позволяют оболочке выполнять различные действия, такие как расширение переменных, но защищают некоторые метасимволы от необходимости экранирования. Одинарные кавычки не позволяют оболочке выполнять эти расширения. Без кавычек оставляет вещи широко открытыми.

$ empty=""
$ text1="some words"
$ grep $empty some_file
(It seems to hang, but it's just waiting for input since it thinks "some_file" is 
the pattern and no filename was entered, so it thinks input is supposed to come
from standard input. Press Ctrl-d to end it.)
$ grep "$empty" some_file
(The whole file is shown since a null pattern matches everything.)
$ grep $text1 some_file
grep: words: No such file or directory
some_file:something
some_file:some words
(It sees the contents of the variable as two words, the first is seen as the 
pattern, the second as one file and the filename as a second file.)
$ grep "$text1" some_file
some_file:some words
(Expected results.)
$ grep '$text1' some_file
(No results. The variable isn't expanded and the file doesn't contain a
string that consists of literally those characters (a dollar sign followed
by "text1"))

Вы можете узнать больше в разделе "QUOTING" man bash

1

Посмотрите на команду xargs . Вы должны быть в состоянии сделать что-то вроде:

grep 'marker-1234' filter_log | xargs grep "(" | вырезать -c1-15

Это может быть не совсем так, но xargs - это команда, которую вы хотите использовать

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .