Подтвердить что ты не робот

Grepping, используя результат предыдущего grep

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

ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content

Во-первых, я хотел бы grep весь файл файла журнала, чтобы увидеть, присутствует ли "xyz". Если это так, я хотел бы получить идентификационный номер этого события и grep через все строки в файле с идентификационным номером, который ищет код состояния.

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

grep "xyz occured" file.log | awk '{ print $2 }' | xargs grep "status code" | awk '{print $NF}'

Любые идеи о том, как это сделать на самом деле?

4b9b3361

Ответ 1

Ты почти там. Но в то время как xargs иногда можно использовать, чтобы делать то, что вы хотите (в зависимости от того, как следующая команда принимает свои аргументы), вы фактически не используете его для grep для только что извлеченного вами идентификатора. Вам нужно сделать вывод первого grep (содержащего идентификационный код) и использовать его в следующем выражении grep. Что-то вроде:

grep "^ID `grep 'xyz occured' file.log | awk '{print $2}'` status code" file.log

Очевидно, что другим вариантом было бы написать script, чтобы сделать это за один проход, a-la Ed.

Ответ 2

Общий ответ на grep-ed вывод:

grep 'patten1' *.txt | grep 'pattern2' 

обратите внимание, что второй grep не указывает на файл.

Подробнее о прохладном grep-материале здесь

Ответ 3

Просто используйте awk:

awk '{info[$2] = info[$2] $0 ORS} /xyz occured/{ids[$2]} END{ for (id in ids) printf "%s",info[id]}' file.log

или

awk '/status code/{code[$2]=$NF} /xyz occured/{ids[$2]} END{ for (id in ids) print code[id]}' file.log

в зависимости от того, что вы действительно хотите вывести. Некоторые ожидаемые результаты в вашем вопросе помогут.

Ответ 4

Grep результат предыдущего Grep:

Учитывая это содержимое файла:

ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content

Эта команда:

grep "xyz" file.log | awk '{ print $2 }' > f.log; grep `cat f.log` file.log;

возвращает это:

ID 1000 xyz occured
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content

Он ищет "xyz" в файле .log помещает результат в f.log. Затем greps для этого идентификатора в файле .log. Если внешний grep возвращает несколько идентификационных номеров, тогда внутренний grep будет искать только первый идентификационный номер и ошибку на других.

Ответ 5

Еще один способ

for x in `grep "xyz occured" file.log | cut -d\  -f2`
do
  grep $x file.log
done

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

grep $x file.log >> /var/tmp/$x.out

Ответ 6

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

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

Попытка найти общий ответ:

1) Создайте список с результатом первого grep:

grep pattern | awk -F':' '{print $1}'

2) Второй grep в список файлов, таких как здесь

xargs grep -i pattern

3) примените этот каскадный фильтр к тому времени, когда вам нужно просто добавить awk, чтобы получить только имена файлов и xargs, чтобы передать имена файлов в grep -i

Например:

grep 'pattern1' | awk -F':' '{print $1}' | xargs grep -i 'pattern2'