Вопрос grepping подстрока из результата grep


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

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
2018-04-09 01:18


происхождения


Это звучит очень программируемо, даже простые команды bash, такие как Grep а также AWK на мой взгляд, лучше ответил на stackoverflow. - Josh K
@Josh: SU имеет много воинов командной строки Linux, которые могут справиться с таким вопросом, и это приветствуется здесь. это может быть один из тех вопросов, которые подойдут на любом сайте, так что это действительно зависит от искателя. - quack quixote
Я подумал, и, честно говоря, я не знал, где его разместить. Я пошел с названиями сайтов, считая, что SO является более общим, а SU - больше. Я считаю, что самые быстрые сценарии оболочки связаны с администратором. Разумеется, вы по каким-то причинам входите в большие эксклюзивные проекты tcl или bash, и в этом случае я бы сузил его до программирования и сообщения для SO. Это было больше одного лайнера, и SU казался хорошим домом. Извините, если я разместил не в том месте, но в некоторых случаях кажется серым. - user17245
@allentown: на самом деле ошибка сервера больше, чем у администратора; Суперпользователь больше подходит для конечных пользователей. (но конечные пользователи с конечным пользователем). В любом случае, этот вопрос, вероятно, приветствуется на любом из SO / SF / SU. вы уже приняли ответ, поэтому, если вы удовлетворены, вы можете это сделать. или если вы хотите, чтобы мы могли перенести его на SO / SF; просто отметьте это для внимания модератора и сообщите нам, куда его отправить. благодаря! - quack quixote
@quack: Все в порядке, я просто подумал, что там можно найти лучший ответ, однако кажется, что он уже найден. - Josh K


ответы:


Я не знаю, на какой ОС вы находитесь, но на 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.


7
2018-04-09 02:28



Я думаю, что все ответы здесь - отличные способы обучения и приближения к конечному результату с тем же ответом. Мне особенно нравится этот, поскольку он легко запоминается и просто соединяет несколько команд grep с цепочкой. В Mac OS X у меня, похоже, есть опция -o, и, конечно, вы используете параметр -E уже довольно часто. Спасибо за ваш ответ - user17245


вы можете сделать все это только одним 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)

3
2018-04-09 02:44



Спасибо, что работает, awk иногда может повредить вашу голову, но я привык к FOO .... один лайнерский аспект быстрого материала в оболочке. Очень могущественный. - user17245


Вы можете сократить второй 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


2
2018-04-09 04:16



Отличная запись, спасибо. Мне нужно лучше справиться с этим с помощью regad для IFS, я был довольно повешен на этом на днях, но мне удалось заставить IFS играть хорошо. Это ужасно, когда у вас есть IFS и забыл об этом, интересно, wtf продолжается в течение часа. - user17245
Это хорошая идея иметь привычку всегда сохранять ценность IFS и восстановить его как можно скорее: saveIFS="$IFS"; IFS=","; do_something; IFS="$saveIFS"; do_other_stuff - Dennis Williamson
+1 Хороший вызов регулярному выражению, я его не использую, поэтому я склонен быть немного неэффективным. - Chris S


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

grep 'marker-1234' filter_log | xargs grep "(" | cut -c1-15

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


1
2018-04-09 01:38