2012-11-03 5 views
6

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

ADWN 1259 11:00 B23 

ADWN 3009 12:00 B19 

DDWN  723 11:30 B04 

ADWN 1589 14:20 B12 

ADWN 1259 11:10 B23 

DDWN 2534 13:00 B16 

ADWN 3009 11:50 B14 

Это дает мне все матчи:

grep '1259\|3009\|1589' somelog.log 

И это дает мне только первый матч

grep -m 1 '1259\|3009\|1589' somelog.log 

Я хочу вернуть следующее:

ADWN 1259 11:00 B23 

ADWN 3009 12:00 B19 

ADWN 1589 14:20 B12 

I думаю, что создание файла с req uired values, а затем прокручивать файл, передавая каждый номер индивидуально команде grep, даст мне то, что я ищу, но я не нашел примера этого. Есть ли простое решение для этого, является ли цикл лучшим способом справиться с этим, или на этот пример уже был дан ответ в другом месте?

Заранее спасибо за ваши идеи и suggestions--

Клайд

ответ

4

Один из способов, используя awk:

awk '!array[$2]++ && $2 ~ /^1259$|^3009$|^1589$/' file.txt 

Результаты:

ADWN 1259 11:00 B23 
ADWN 3009 12:00 B19 
ADWN 1589 14:20 B12 

редактировать:

Я должен по-настоящему привыкнуть сначала прочитывать весь вопрос. Я вижу, что вы думаете создать файл со значениями, которые вы хотели бы найти в первом случае. Поместите их в файл с именем values.txt с одним значением в строке. Например; вот содержание values.txt:

1259 
3009 
1589 

Затем запустите это:

awk 'FNR==NR { array[$0]++; next } $2 in array { print; delete array[$2] }' values.txt file.txt 

Результаты:

ADWN 1259 11:00 B23 
ADWN 3009 12:00 B19 
ADWN 1589 14:20 B12 

первой команды Объяснение:

Если второй столбец ($2) равно одному из этих трех значений, добавьте его в массив, если он еще не существует. awk печатает всю строку по умолчанию.

вторая команда Объяснение:

FNR является количество записей относительно текущего входного файла.
NR - общее количество записей.

Конструкция FNR==NR { ... } верна только для первого входного файла.Поэтому для каждой из строк в values.txt мы добавляем всю строку ($0) к массиву (я называю его массивом, но вы можете дать ему другое имя). next заставляет awk читать следующую строку в values.txt (и пропустить обработку остальной части команды). Когда FNR==NR больше не верен, считывается второй файл в списке аргументов. Затем мы проверяем второй столбец ($2) в массиве, если он там, распечатаем его и удалим из массива. Используя delete, мы по существу устанавливаем максимальное количество единиц.

+0

Steve - спасибо, это то, что я спросил, он возвращает первое появление каждого значения. У меня есть некоторое чтение, чтобы сделать на awk и понять, что делает код –

+1

Я могу добавить краткое объяснение, если вы хотите. Повесьте там ... – Steve

+0

Ницца, я ценю объяснение - некоторые из этих вещей могут быть довольно непрозрачными! Я обязательно смогу использовать это, спасибо снова! –

-1

Попробуйте это. Она не может работать в зависимости от версии Grep:

grep -m 1 -e pattern1 -e pattern2 
+0

Спасибо, к сожалению, этот фрагмент вернул только первый образец, спасибо. –

0

Вы можете использовать для каждого (см Linux Shell Script For Each File in a Directory Grab the filename and execute a program) Для каждого шаблона вы хотите, чтобы соответствовать выполнить отдельный Grep конкатенации в выходной файл

+0

Это идея, о которой я думал, спасибо за указатель! –

0

Это один будет работа тоже.

for i in $(cut -d " " -f1 somelog.log | sort -u); do LC_ALL=C fgrep -m1 "$i" somelog.log; done 
Смежные вопросы