2013-02-13 3 views
3

мне нужна помощь со следующими:awk | слияние линии на основе поля, соответствующего

входного файла:

abc message=sent session:111,x,y,z 
pqr message=receive session:111,4,5,7 
abc message=sent session:123,x,y,z 
pqr message=receive session:123,4,5,7 
abc message=sent session:342,x,y,z 
abc message=sent session:589,x,y,z 
pqr message=receive session:589,4,5,7 

Выходной файл:

abc message=sent session:111,x,y,z, pqr message=receive session:111,4,5,7 
abc message=sent session:123,x,y,z, pqr message=receive session:123,4,5,7 
abc message=sent session:342,x,y,z, NOMATCH 
abc message=sent session:589,x,y,z, pqr message=receive session:589,4,5,7 

Примечания:

Если вы видите исходный файл, для каждого «отправленного» сообщения есть «принимать»
только для сеанса = 342 нет приема
сессия неизвестная, не может быть жёстко
Так сливаться только посланными и получить где мы соответствие номера сеанса

+0

ли сообщение = получать всегда следует сообщение = отправлено немедленно, как в этом примере? – jkerian

+0

не всегда. Если есть сообщение «message = sent» и «message = receive» для того же сеанса, тогда только объединяйте –

+0

, также если вы видите, то у нас есть 2 сообщения = отправлено (один за другим) в примере, что означает, что мне нужно пропустить одно отправленное и продолжить со следующей строкой –

ответ

1

Другой способ:

awk -F "[:,]" '/=sent/{a[$2]=$0;}/=receive/{print a[$2], $0;delete a[$2];}END{for(i in a)print a[i],"NO MATCH";}' file 

Результаты:

abc message=sent session:111,x,y,z pqr message=receive session:111,4,5,7 
abc message=sent session:123,x,y,z pqr message=receive session:123,4,5,7 
abc message=sent session:589,x,y,z pqr message=receive session:589,4,5,7 
abc message=sent session:342,x,y,z NO MATCH 

Когда send запись встречается, то магазин в массиве с идентификатором сессии в качестве индекса. Когда встречается запись receive, запись send извлекается из массива и печатается вместе с записью receive. Кроме того, отправленные записи удаляются из массива как и когда принимаются receive записей. В END все остальные записи в массиве печатаются как NO MATCH.

+0

Большое спасибо за это .. но я не могу понять логику .. не могли бы вы объяснить это –

+0

обновлено с комментариями – Guru

+0

Thats really easy to understand .. thanks Guru –

1

Вот один из способов использования awk. Бегите как:

awk -f script.awk file 

Содержание script.awk:

{ 
    x = $0 

    gsub(/[^:]*:|,.*/,"") 

    a[$0] = (a[$0] ? a[$0] "," FS : "") x 
    b[$0]++ 
} 

END { 
    for (i in a) { 
     print (b[i] == 2 ? a[i] : a[i] "," FS "NOMATCH") | "sort" 
    } 
} 

Результаты:

abc message=sent session:111,x,y,z, pqr message=receive session:111,4,5,7 
abc message=sent session:123,x,y,z, pqr message=receive session:123,4,5,7 
abc message=sent session:342,x,y,z, NOMATCH 
abc message=sent session:589,x,y,z, pqr message=receive session:589,4,5,7 

В качестве альтернативы, вот один вкладыш:

awk '{ x = $0; gsub(/[^:]*:|,.*/,""); a[$0] = (a[$0] ? a[$0] "," FS : "") x; b[$0]++ } END { for (i in a) print (b[i] == 2 ? a[i] : a[i] "," FS "NOMATCH") | "sort" }' file 

Обратите внимание, что вы можете упасть труба до sort, если вам не нужен сортированный выход. НТН.

+0

Здравствуйте, Стив. Не могли бы вы объяснить логику и почему мы ставим сортировку в конце? –

Смежные вопросы